jquery – 保持窗口不改变滚动位置,同时将项目添加到列表中?

我有一个页面显示消息,我希望它像Facebook一样工作,但没有懒惰的加载器。 消息按时间顺序显示,最近一次显示。

我的消息列表最初填充了x个最新消息,窗口滚动到底部。 当用户开始阅读该post时,他们会从下到上阅读。 如果他们到达顶部,他们可以加载更多消息…我让他们点击一个按钮… facebook有一个懒惰的加载器。 新消息将添加到列表中。

问题:由于新消息被预先添加,现有消息被推下,导致用户失去“查看”位置。 在添加新消息时,如何保持用户当前的查看位置? 例如,在Facebook中打开一个长消息线程,滚动到顶部导致添加新消息…即使滚动位置确实如此,您的视图位置也不会改变。

在添加新消息之前存储对第一条消息的引用,在前置之后,将滚动设置为该消息的偏移量:

$(document).on('scroll', function() { var scroll = $(document).scrollTop(); if (scroll < 1) { // Store eference to first message var firstMsg = $('.message:first'); // Prepend new message here (I'm just cloning...) $('body').prepend(firstMsg.clone()); // After adding new message(s), set scroll to position of // what was the first message $(document).scrollTop(firstMsg.offset().top); } }); 

演示: http : //jsfiddle.net/GRnQY/

编辑 :我注意到你想要一个按钮。 你可能需要做更多的数学运算:

 $(document).on('click', '#loadMore', function() { var firstMsg = $('.message:first'); // Where the page is currently: var curOffset = firstMsg.offset().top - $(document).scrollTop(); // Prepend firstMsg.before(firstMsg.clone()); // Offset to previous first message minus original offset/scroll $(document).scrollTop(firstMsg.offset().top-curOffset); }); 

演示: http : //jsfiddle.net/GRnQY/5/

这里不需要jQuery,只需检查元素scrollHeight中的更改并相应地调整scrollTop,即:

 var lastScrollHeight = el.scrollHeight; for(var n=0; n<10; n++){ // Prepend here... } var scrollDiff = el.scrollHeight - lastScrollHeight; el.scrollTop += scrollDiff; 

演示

http://jsfiddle.net/fkqqv28e/

jQuery的

要从jQuery集合访问本机DOM节点,请使用数组访问; 即:

 var lastScrollHeight = $('#myElement')[0].scrollHeight; for(var n=0; n<10; n++){ $('#myElement').prepend('
prepended '+Math.random()+'
'); } var scrollDiff = $('#myElement')[0].scrollHeight - lastScrollHeight; $('#myElement')[0].scrollTop += scrollDiff;

来到这里的一些人可能只是想在没有当前焦点跳跃的情况下添加内容。 修改上面的Jeff B的演示以使用click事件目标使这个成语更具可移植性:

 someButton.on('click', function() { var curOffset = $(this).offset().top - $(document).scrollTop(); // add content to your heart's content. $(document).scrollTop($(this).offset().top-curOffset); }); 

cf http://jsfiddle.net/bwz8uLvt/1/ (上面的Jeff B演示的变体,但在页面的任意一点有[添加更多]按钮)。

我只是碰到了这个变种。 我分离了大量元素,处理它们然后再次附加它们。 这不能在Chrome中同步完成,所以我无法可靠地设置$ el.scrollTop(oldval)。 我发现这个解决方案对我有用。

 // get old scroll top of '#sub_elem' oldScrollTop = $('#sub_elem).scrollTop(); // detach $els = $('#sub_elem').detach(); // complex processing on #sub_elem // goes here // attach $('#main_el').attach($els); // problem- always scrolls #sub_elem back to the top // attempt #1: $('#sub_elem').scrollTop(oldScrollTop); // fails on mac Chrome // attempt #2: use instant animation. this works on mac Chrome if (oldScrollTop) { $('#sub_elem').animate({ scrollTop: oldScrollTop }, 0); } 

您还可以根据页面/元素底部的偏移量保持滚动位置。

 var ScrollFromBottom = $(document).height() - $(window).scrollTop(); //ajax - add messages -- geenrate html code then add to dom //set scroll position $(window).scrollTop($(document).height() - ScrollFromBottom); 

这是一个对我有用的简单技巧:

 // divWithTheScroll.prependElement... divWithTheScroll.scrollTop += newlyPrependedElement.scrollHeight;