检查用户是否已滚动到底部

Joh*_*nny 635 javascript jquery pagination scroll

我正在创建一个分页系统(有点像Facebook),当用户滚动到底部时,内容会加载.我想最好的方法是找到用户位于页面底部并运行ajax查询以加载更多帖子.

唯一的问题是我不知道如何检查用户是否已使用jQuery滚动到页面底部.有任何想法吗?

我需要找到一种方法来检查用户何时使用jQuery滚动到页面底部.

Nic*_*ver 986

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

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

您可以在此处进行测试,这将采用窗口的顶部滚动,因此向下滚动多少,添加可见窗口的高度并检查它是否等于整个内容的高度(document).如果你想检查用户是否接近底部,它看起来像这样:

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

您可以在此处测试该版本,只需将其调整100为您想要触发的底部的任何像素.

  • 像往常一样,你在我面前到达那里.无论如何,对于OP,如果你有一个容器的帖子,使用它的ID而不是"窗口",你也可以想把最后一个.height()更改为scrollHeight (32认同)
  • @KevinVella Vella良好的组合是在下划线实用程序中使用_.debounce()来阻止它在用户停止滚动之前触发 - http://underscorejs.org/#debounce- (18认同)
  • 它很棒!但是不是有点沉重吗?在每个卷轴上? (11认同)
  • 如果用户放大或缩小浏览器,我将无法工作. (11认同)
  • Firefox调用alert("bottom!"); 很多次(与铬和野生动物园一起工作很好) (3认同)
  • 它有点儿,如果你做一个`console.log()`而不是警告,它有时会重复命令. (3认同)
  • @NickCraver有没有可用的纯js实现? (2认同)
  • 这曾经很好用,但现在我在 1920 * 1080 屏幕上有问题 (2认同)

Mil*_*efe 113

尼克克拉弗的答案运作良好,免除了$(document).height()浏览器价值的变化.

要使其适用于所有浏览器,请使用James Padolsey的此功能:

function getDocHeight() {
    var D = document;
    return Math.max(
        D.body.scrollHeight, D.documentElement.scrollHeight,
        D.body.offsetHeight, D.documentElement.offsetHeight,
        D.body.clientHeight, D.documentElement.clientHeight
    );
}
Run Code Online (Sandbox Code Playgroud)

代替$(document).height(),以便最终的代码是:

$(window).scroll(function() {
       if($(window).scrollTop() + $(window).height() == getDocHeight()) {
           alert("bottom!");
       }
   });
Run Code Online (Sandbox Code Playgroud)

  • 他更新了一个稍微压缩的版本函数getDocHeight(){var D = document; 返回Math.max(D.body.scrollHeight,D.documentElement.scrollHeight,D.body.offsetHeight,D.documentElement.offsetHeight,D.body.clientHeight,D.documentElement.clientHeight); } (6认同)

Fél*_*ier 92

我不确定为什么还没有发布,但根据MDN的文档,最简单的方法是使用本机javascript属性:

element.scrollHeight - element.scrollTop === element.clientHeight
Run Code Online (Sandbox Code Playgroud)

当您位于任何可滚动元素的底部时,返回true.所以简单地使用javascript:

element.addEventListener('scroll', function(event)
{
    var element = event.target;
    if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        console.log('scrolled');
    }
});
Run Code Online (Sandbox Code Playgroud)

scrollHeight在浏览器中有广泛的支持,从8到更精确,同时clientHeight并且scrollTop每个人都支持.即使是6.这应该是跨浏览器安全的.

  • `Math.abs(element.scrollHeight - element.scrollTop - element.clientHeight)<= 3.0`(用您认为适合您情况的任何像素容差替换3.0).这是要走的路,因为(A)`clientHeight`,`scrollTop`和`clientHeight`都是四舍五入的,这可能会导致3px错误,如果所有对齐,(B)3像素对用户几乎不可见,那么当用户"认为"他们位于页面底部时实际上他们不是这样,并且(C)某些设备(尤其是没有鼠标的设备)在滚动时可能会有奇怪的行为. (6认同)

小智 48

对于那些使用Nick的解决方案并获得重复警报/事件触发的人,您可以在警报示例上方添加一行代码:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       $(window).unbind('scroll');
       alert("near bottom!");
   }
});
Run Code Online (Sandbox Code Playgroud)

这意味着代码只会在您第一次在文档底部的100px范围内时触发.如果您向上滚动然后向下滚动,它将不会重复,根据您使用的尼克代码,这可能有用也可能没有用.


Geo*_*kos 40

除了Nick Craver的优秀接受答案之外,您可以限制滚动事件,以便不会频繁触发,从而提高浏览器性能:

var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);

$document.ready(function () {

    $window
        .off('scroll', ScrollHandler)
        .on('scroll', ScrollHandler);

});

function ScrollHandler(e) {
    //throttle event:
    clearTimeout(_throttleTimer);
    _throttleTimer = setTimeout(function () {
        console.log('scroll');

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

    }, _throttleDelay);
}
Run Code Online (Sandbox Code Playgroud)

  • 上面的代码不需要Underscore.js (34认同)

Yos*_*osi 37

Nick Craver的答案需要稍加修改才能在iOS 6 Safari Mobile上运行,应该是:

$(window).scroll(function() {
   if($(window).scrollTop() + window.innerHeight == $(document).height()) {
       alert("bottom!");
   }
});
Run Code Online (Sandbox Code Playgroud)

更改$(窗口).height()window.innerHeight应该做的事,因为当地址栏被隐藏额外的60像素被添加到窗口的高度,但使用$(window).height()没有反映这种变化,同时使用window.innerHeight呢.

注意:该window.innerHeight属性还包括水平滚动条的高度(如果已渲染),与$(window).height()此不同,它不包括水平滚动条的高度.这在Mobile Safari中不是问题,但可能会在其他浏览器或未来版本的Mobile Safari中导致意外行为.更改==>=可以解决大多数常见用例.

这里阅读更多关于该window.innerHeight物业


Fre*_*tte 18

这是一个相当简单的方法:

elm.onscroll = function() {
    if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) //User has scrolled to the bottom of the element
}
Run Code Online (Sandbox Code Playgroud)


Tal*_*lon 15

这是一段代码,可以帮助您调试代码,我测试了上面的答案,发现它们是错误的.我在Chrome,IE,Firefox,iPad(Safari)上测试了以下内容.我没有安装任何其他测试...

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var winElement = $(window)[0];

         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
            alert('bottom');
         }
      });
   });
</script>
Run Code Online (Sandbox Code Playgroud)

可能有一个更简单的解决方案,但我停止了IT工作的时间点

如果你仍然遇到一些流氓浏览器的问题,这里有一些代码可以帮你调试:

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var details = "";
         details += '<b>Document</b><br />';
         details += 'clientHeight:' + docElement.clientHeight + '<br />';
         details += 'clientTop:' + docElement.clientTop + '<br />';
         details += 'offsetHeight:' + docElement.offsetHeight + '<br />';
         details += 'offsetParent:' + (docElement.offsetParent == null) + '<br />';
         details += 'scrollHeight:' + docElement.scrollHeight + '<br />';
         details += 'scrollTop:' + docElement.scrollTop + '<br />';

         var winElement = $(window)[0];
         details += '<b>Window</b><br />';
         details += 'innerHeight:' + winElement.innerHeight + '<br />';
         details += 'outerHeight:' + winElement.outerHeight + '<br />';
         details += 'pageYOffset:' + winElement.pageYOffset + '<br />';
         details += 'screenTop:' + winElement.screenTop + '<br />';
         details += 'screenY:' + winElement.screenY + '<br />';
         details += 'scrollY:' + winElement.scrollY + '<br />';

         details += '<b>End of page</b><br />';
         details += 'Test:' + (docElement.scrollHeight - winElement.innerHeight) + '=' + winElement.pageYOffset + '<br />';
         details += 'End of Page? ';
         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
             details += 'YES';
         } else {
             details += 'NO';
         }

         $('#test').html(details);
      });
   });
</script>
<div id="test" style="position: fixed; left:0; top: 0; z-index: 9999; background-color: #FFFFFF;">
Run Code Online (Sandbox Code Playgroud)

我希望这能节省一些时间.


Jun*_*dir 12

请检查这个答案

 window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
       console.log("bottom");
    }
};
Run Code Online (Sandbox Code Playgroud)

您可以footerHeight - document.body.offsetHeight查看是否靠近页脚或到达页脚


小智 11

这是我的两分钱:

$('#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');
        }
    });
Run Code Online (Sandbox Code Playgroud)


Vas*_*nyk 11

var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
Run Code Online (Sandbox Code Playgroud)

它计算距离滚动条到元素的底部.如果滚动条已到达底部,则等于0.


Ste*_*rya 7

使用Intersection Observer来检查最后一个元素是否在视口上可见(这意味着用户已滚动到底部),而不是侦听滚动事件,这是一种廉价的方法。它还支持带有polyfill的Internet\xc2\xa0Explorer\xc2\xa07

\n

\r\n
\r\n
var observer = new IntersectionObserver(function(entries){\n   if(entries[0].isIntersecting === true)\n      console.log("Scrolled to the bottom");\n   else\n      console.log("Not on the bottom");\n}, {\n   root:document.querySelector(\'#scrollContainer\'),\n   threshold:1 // Trigger only when whole element was visible\n});\n\nobserver.observe(document.querySelector(\'#scrollContainer\').lastElementChild);
Run Code Online (Sandbox Code Playgroud)\r\n
#scrollContainer{\n  height: 100px;\n  overflow: hidden scroll;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div id="scrollContainer">\n  <div>Item 1</div>\n  <div>Item 2</div>\n  <div>Item 3</div>\n  <div>Item 4</div>\n  <div>Item 5</div>\n  <div>Item 6</div>\n  <div>Item 7</div>\n  <div>Item 8</div>\n  <div>Item 9</div>\n  <div>Item 10</div>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n


l2a*_*lba 5

纯JS跨浏览器debouncing (相当不错的性能)

var CheckIfScrollBottom = debouncer(function() {
    if(getDocHeight() == getScrollXY()[1] + window.innerHeight) {
       console.log('Bottom!');
    }
},500);

document.addEventListener('scroll',CheckIfScrollBottom);

function debouncer(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}
function getScrollXY(){var a=0,b=0;return"number"==typeof window.pageYOffset?(b=window.pageYOffset,a=window.pageXOffset):document.body&&(document.body.scrollLeft||document.body.scrollTop)?(b=document.body.scrollTop,a=document.body.scrollLeft):document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)&&(b=document.documentElement.scrollTop,a=document.documentElement.scrollLeft),[a,b]}
function getDocHeight(){var a=document;return Math.max(a.body.scrollHeight,a.documentElement.scrollHeight,a.body.offsetHeight,a.documentElement.offsetHeight,a.body.clientHeight,a.documentElement.clientHeight)}
Run Code Online (Sandbox Code Playgroud)

演示: http ://jsbin.com/geherovena/edit?js,output

PS: ,,Debouncer 不是我写的getScrollXYgetDocHeight

我只是展示它的工作方式,以及我将如何做


Flo*_*rei 5

尼克回答说很好,但是您将拥有在滚动时重复自身的功能,或者如果用户缩放了窗口,则根本无法工作。我想出了一个简单的解决方案,只需 math.round 第一个高度,它的工作原理就像假设的那样。

    if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
    loadPagination();
    $(".go-up").css("display","block").show("slow");
}
Run Code Online (Sandbox Code Playgroud)


Bak*_*nce 5

我的普通js解决方案:

let el=document.getElementById('el');
el.addEventListener('scroll', function(e) {
    if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) {
        alert('Bottom');
    }
});
Run Code Online (Sandbox Code Playgroud)
#el{
  width:400px;
  height:100px;
  overflow-y:scroll;
}
Run Code Online (Sandbox Code Playgroud)
<div id="el">
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>
Run Code Online (Sandbox Code Playgroud)


Abh*_*ngh 5

我用纯 JavaScript 以一种非常简单的方式完成了这一点:

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