时间:2015-12-21 22:07:37

标签: javascript dom meteor

我有一个meteor.js个应用程序,可以充当新闻源,其中发布了线程,人们可以实时评论线程。这意味着当您查看帖子时,会在上方和下方的帖子中添加新评论,并在上方添加新帖子。这会将你正在关注的帖子推到视口之外,这是从未预料到的(除非你已经滚动到顶部)。

更新滚动以保持与添加新内容相同的视觉中心的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

您可以尝试这种方法:

  1. 保存scrollTop值;
  2. 预先添加内容(例如,在重点关注的内容之上添加新帖子);
  3. 将新内容的高度添加到步骤1中保存的值;
  4. 滚动到新值。
  5. 以下是一个例子:

    
    
    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);
    });
    &#13;
    #content {
      height: 100px;
      overflow-y: scroll;
    }
    .post {
      height: 40px;
    }
    &#13;
    <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>
    &#13;
    &#13;
    &#13;

    将内容添加到当前视口下方不应该进行调整。

    Here's a blog post描述了类似的方法,以及similar SO question

答案 1 :(得分:1)

我建议您这样做,当要添加新项目时,检查您是否在顶部,如果是,则只需添加新项目。

如果没有,您将获得项目容器的现有顶部/高度,添加新项目,再次获取项目容器高度,然后更新滚动顶部。

以下是一个简单的示例,说明如何做到,在顶部和底部添加(顺便说一下,在底部不需要滚动补偿)。

&#13;
&#13;
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);
}
&#13;
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; }
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以使用包animated-each meteor add mizzao:animated-each来解决问题。

这肯定比实现自定义jquery更好。如果包没有解决确切的问题,那么你可以用它作为一个例子来说明如何挂钩渲染并以流星方式创建解决方案。可能利用meteor-ui-hooks