我正在制作一个分页系统(有点像Facebook),当用户滚动到底部时,内容就会加载。我认为最好的方法是找到用户在页面底部的时间,然后运行Ajax查询来加载更多的帖子。

唯一的问题是我不知道如何检查用户是否已经滚动到页面的底部。什么好主意吗?

我使用jQuery,所以请随意提供使用它的答案。


当前回答

TL; diana;

Math.abs(element.scrollHeight - element.scrollTop - element.clientHeight) < 1

概念

在其核心,“已经滚动到底部”指的是可滚动区域(scrollHeight)减去可见内容到顶部(scrollTop)的距离等于可见内容的高度(clientHeight)的时刻。

换句话说,当这个等价为真时,我们被“滚动”::

scrollHeight - scrollTop - clientHeight === 0

防止舍入错误

但是,如上所述,其中一些属性是四舍五入的,这意味着在scrollTop有小数组件或四舍五入值对齐不好的情况下,相等性可能会失败。

通过将绝对差异与可容忍的阈值进行比较,可以缓解这个问题:

Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 1

防止舍入错误的代码片段如下所示:

. getelementbyid(“constrained-container”)。addEventListener('scroll', event => { const {scrollHeight, scrollTop, clientHeight} = event.target; 如果(数学。abs(scrollHeight - clientHeight - scrollTop) < 1) { console.log(滚动); } }); # constrained-container { 身高:150 px; overflow-y:滚动; } # very-long-content { 身高:600 px; } < div id = " constrained-container " > < div id = " very-long-content " > 把我滚动到底部 < / div > < / div >

注意,我添加了一个div,对于它的容器来说,它太大了,无法强制滚动,但没有必要将内容“包装”到另一个元素中,直接在元素中输入文本会使元素溢出。

跳脱,延迟和节流

我对它了解得越多,我发现它在这个答案的范围内就越少(这个codereview问题及其答案,以及这篇链接的文章都很有趣),但在特定情况下(如果处理程序执行昂贵的计算,如果我们将动画绑定到滚动事件,如果我们只想在滚动运动结束时启动事件,或者任何可能保证它的情况),它可以用于:

Debounce(当第一次滚动发生时触发处理程序,然后防止它太快触发), 延迟(阻止处理程序的执行,直到滚动事件在一段时间内没有触发。这在Ecmascript上下文中通常被称为deboning), 或者节流(防止训练者在一段时间内射击一次以上)。

在选择做这些事情时必须非常小心,例如,限制事件可以防止最后一个卷轴发射,这可能会完全击败无限卷轴。

大多数时候,不做这三件事中的任何一件都是完美的,因为仅仅看看我们是否完全滚动是相对便宜的。

其他回答

Safari可以滚动到导致应用程序错误的页面底部。用>=代替===来解决这个问题。

container.scrollTop >= container.scrollHeight - container.clientHeight

这是我的观点:

$('#container_element').scroll( function(){
        console.log($(this).scrollTop()+' + '+ $(this).height()+' = '+ ($(this).scrollTop() + $(this).height())   +' _ '+ $(this)[0].scrollHeight  );
        if($(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight){
            console.log('bottom found');
        }
    });

我已经用纯JS做了这个非常简单的方法。

function onScroll() {    
    if (window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight - 50) {
        Console.log('Reached bottom')
    }
}
window.addEventListener("scroll", onScroll);

我使用@ddanone answear并添加Ajax调用。

$('#mydiv').on('scroll', function(){
  function infiniScroll(this);
});

function infiniScroll(mydiv){
console.log($(mydiv).scrollTop()+' + '+ $(mydiv).height()+' = '+ ($(mydiv).scrollTop() + $(mydiv).height())   +' _ '+ $(mydiv)[0].scrollHeight  );

if($(mydiv).scrollTop() + $(mydiv).height() == $(mydiv)[0].scrollHeight){
    console.log('bottom found');
    if(!$.active){ //if there is no ajax call active ( last ajax call waiting for results ) do again my ajax call
        myAjaxCall();
    }
}

}

在window上使用.scroll()事件,如下所示:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() == $(document).height()) {
       alert("bottom!");
   }
});

你可以在这里测试它,这取窗口的顶部滚动,所以它向下滚动了多少,添加可见窗口的高度,并检查它是否等于整体内容(文档)的高度。如果你想检查用户是否在底部附近,它看起来像这样:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       alert("near bottom!");
   }
});

你可以在这里测试这个版本,只要调整100到你想要触发的底部像素。