【问题标题】:Infinite scroll doesn't work when scrolled all the way to the end of the div一直滚动到 div 末尾时,无限滚动不起作用
【发布时间】:2019-04-03 00:11:03
【问题描述】:

我正在尝试在我的聊天中无限滚动。我正在使用滚动事件来检查是否scrolltop < clientHeight 并调用函数loadMore 如果是。只要您从不滚动到最顶部,这就会很好地工作。我制作了一个 gif 来展示这一点(希望它有意义):

如果在加载较旧的消息时您仍有更多的滚动空间,您可以保留您的位置,并且滚动条会被向下推。

但是,如果您在加载较旧的消息时一直滚动到顶部,则滚动条将保持固定在顶部并且您会失去位置(滚动事件也会停止触发,因此您会停止加载消息,除非您向下滚动一点)

有其他人经历过吗?你做了什么来解决它?任何建议表示赞赏。谢谢!

【问题讨论】:

  • 能否提供在滚动事件上执行的代码?
  • 字面意思是if (scrollTop < clientHeight) { loadMoreMessages() }@Y.Gherbi

标签: javascript html scroll chat infinite-scroll


【解决方案1】:

更新了答案以支持 2 个方向(向上或向下)和加载填充。请在展开模式下运行 sn-p,内联预览框对于可滚动列表来说太小了。

var isLoadingAlready = false;
var upDirection = true; // to load records on top of the list; false to load them to the end of the list
var loadThreshold = 100; // distance to the edge (in pixels) to start loading
var howManyDataLoadsAvailable = 5;

if (upDirection){
    $('.scroll')[0].scrollTop = 100000; // scrolling all the way down
    $('.scroll').css('paddingTop', loadThreshold);
} else {
    $('.scroll').css('paddingBottom', loadThreshold);
}

$('.scroll').on('scroll', function () {
    var s = this; // picking DOM element

    if (s) { // just to be sure/safe
        var scrollableHeight = s.scrollHeight - s.clientHeight;
        if (scrollableHeight > 0) {
            var scrollTop = s.scrollTop;
            var distToTheEdge = upDirection?scrollTop:scrollableHeight - scrollTop;
            if (distToTheEdge < loadThreshold && !isLoadingAlready) {
                isLoadingAlready = true;
                loadMoreRecords(function () { // assuming you have a callback to allow next loading
                    isLoadingAlready = false;
                });
            }
        }
    }
});

loadMoreRecords();

function loadMoreRecords(doneCallback){
    $('.scroll').addClass('loading');

    // simulating the actual loading process with setTimeout
    setTimeout(function(){
        // simulated items to insert:
        var items = [];
        if (howManyDataLoadsAvailable-- > 0){
            for (var i = 0; i < 10; i++){
                items.push($('<li>').text('msg: '+(i+1)+', parts left: '+howManyDataLoadsAvailable));
            }
        }

        var $se = $('.scroll'); // scrollable DOM element
        var $ul = $('.scroll ul');
        var se = $se[0];
        if (upDirection) {
            var hBefore = $ul.height();
            $ul.prepend(items);
            var hDiff = $ul.height() - hBefore;
            se.scrollTop = Math.max(hDiff, loadThreshold);
        } else {
            $ul.append(items);
            se.scrollTop = se.scrollHeight - se.clientHeight - Math.max(se.scrollHeight - se.clientHeight - se.scrollTop, loadThreshold);
        }
        $se.removeClass('loading');
        if (typeof(doneCallback) === 'function'){
            doneCallback();
        }
    }, 500);
}
.scroll{
  overflow-y: auto;
  max-height: 200px;
  border: 2px dashed #aaa;
  padding: 0.5em;
  margin: 1em;
}
.scroll.loading{
  background-color: #f5f5f5;
}

ul{
  list-style: none;
  padding: 0;
}

li{
  padding: 0.5em;
  border: 1px solid #eee;
  border-radius: 0.5em;
  margin: 0.2em;
  animation: colorchange 1200ms;
  background: white;
  box-shadow: 1px 1px 5px 0px rgba(0,0,0,0.05);
}


@keyframes colorchange
{
  0%   {background: #def;}
  100% {background: white;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div class="scroll">
  <ul></ul>
</div>

【讨论】:

  • 老兄,你摇滚!修复它的行是se.scrollTop = Math.max(hDiff, loadThreshold); 我不确定我明白为什么.. 你能解释一下吗?
  • @EgorEgorov 需要确保您不违反触发加载的边界。所以它会滚动到最后一个添加的项目(使用所有添加项目的高度),但如果它比那个边界更近(项目太少或填充不够) - 你将被放置在后面的“安全”位置边境。我希望这是有道理的)
猜你喜欢
  • 2020-10-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
相关资源
最近更新 更多