Block scrolling when adding new content at the top and bottom

I have a meteor.js application that functions as a news feed, with streams being published and people commenting on streams in real time. This means that while you look at the post, new comments are added to the posts above and below, and new threads will be added above. This will lead to the fact that the message will be focused on the drop-down and leaving the viewport, which is never expected (if you have not already scrolled at the top).

What is the best way to update scrolls to support the same visual center as new content?

+5
source share
3 answers

You can try this approach:

  • save scrollTop value;
  • add content (i.e. add a new record above the one that is focused);
  • add the height of the new content to the value stored in step 1;
  • Highlight the new value.

Here is an example:

 function randomString() { return Math.random().toString(36).substring(7); } $('#addAbove').on('click', function(e){ var newDiv = $('<li class="post">' + randomString() + '</li>'); var savedScrollTop = $('#content').scrollTop(); $('#content').prepend(newDiv); $('#content').scrollTop(savedScrollTop + newDiv.height()); }); $('#addBelow').on('click', function(e){ var newDiv = $('<li class="post">' + randomString() + '</li>'); $('#content').append(newDiv); }); 
 #content { height: 100px; overflow-y: scroll; } .post { height: 40px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul id="content"> <li class="post">u9tv190be29</li> <li class="post">dgdr8gp66rp</li> <li class="post">93vfntdquxr</li> </ul> <button id="addAbove">Add Above</button> <button id="addBelow">Add Below</button> 

Adding content below the current view does not require configuration.

Here's a blog post describing a similar approach and a similar SO question .

+3
source

I suggest you do so when a new item needs to be added, you check if you are at the top, if so, just add a new item.

If not, you get the existing top / top container of your item, add a new item, increase the height of the item container and then update the top of the scroll.

Here is a simple example of how you can do it by adding both top and bottom (by the way, scroll compensation is not required below).

 function addItem (totop) { var msgdiv = document.getElementById('items'); var attop = scrollAtTop(msgdiv); var prevtop = parseInt(msgdiv.scrollHeight - msgdiv.scrollTop); if (totop) { msgdiv.innerHTML = 'Long long content ' + (tempCounter++) + '!<br/>' + msgdiv.innerHTML; if (!attop) { updateScroll(msgdiv, parseInt(msgdiv.scrollHeight) - prevtop); } } else { msgdiv.innerHTML += 'Long long content ' + (tempCounter++) + '!<br/>'; } } var tempCounter = 10; function updateScroll(el, top){ el.scrollTop = top; } function scrollAtTop(el){ return (el.scrollTop == 0); } 
 html, body { height:100%; margin:0; padding:0; } .items{ display: inline-block; width: 300px; height: 220px; border: 1px solid black; overflow: auto; } button { width: 15%; height: 44px; margin: 20px; vertical-align: top; } 
 <div class="items" id="items"> Long long content 9!<br/> Long long content 8!<br/> Long long content 7!<br/> Long long content 6!<br/> Long long content 5!<br/> Long long content 4!<br/> Long long content 3!<br/> Long long content 2!<br/> Long long content 1!<br/> </div> <button onclick="addItem(true);">Add 2 top</button><button onclick="addItem(false);">Add 2 bottom</button> 
+1
source

You can use the animated-each meteor add mizzao:animated-each package to solve the problem.

This would be better than implementing a custom jquery. And if the package does not solve the exact problem, you can use it as an example of how to connect to the rendering and create a solution for the meteor shower. Perhaps using meteor-ui-hooks

+1
source

Source: https://habr.com/ru/post/1238890/


All Articles