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

时间:2010-10-09 22:28:45

标签: javascript jquery scroll pagination

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

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

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

29 个答案:

答案 0 :(得分:940)

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

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

You can test it here,它采用窗口的顶部滚动,因此向下滚动多少,添加可见窗口的高度并检查它是否等于整个内容的高度(document) 。如果你想检查用户是否底部附近,它看起来像这样:

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

You can test that version here,只需将100调整为您想要触发的底部的任何像素。

答案 1 :(得分:111)

尼克克拉弗的答案很好,除了$(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
    );
}

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

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

答案 2 :(得分:80)

我不确定为什么还没有发布,但根据the documentation from MDN,最简单的方法是使用原生的javascript属性:

element.scrollHeight - element.scrollTop === element.clientHeight

当您位于任何可滚动元素的底部时,返回true。所以只需使用javascript:

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

scrollHeight在浏览器中得到了广泛的支持,从8开始更精确,而clientHeightscrollTop都得到了所有人的支持。即使是6.这应该是跨浏览器的安全。

答案 3 :(得分:47)

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

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

这意味着代码只会在您第一次在文档底部的100px范围内时触发。如果您向上滚动然后向后滚动,它将不会重复,这可能会或可能没有用,这取决于您使用Nick的代码。

答案 4 :(得分:39)

除了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);
}

答案 5 :(得分:36)

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

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

$(窗口).height() 更改为 window.innerHeight 应该完成,因为当地址栏被隐藏了另外60px被添加到窗口的高度,但使用$(window).height() 反映了此更改,而使用window.innerHeight时却是如此。

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

详细了解window.innerHeight属性here

答案 6 :(得分:19)

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

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

答案 7 :(得分: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>

可能有一个更简单的解决方案,但我停在 IT WORKED

的时刻

如果您仍然遇到某些流氓浏览器的问题,可以使用以下代码来帮助您进行调试:

<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;">

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

答案 8 :(得分:10)

这是我的两分钱:

$('#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');
        }
    });

答案 9 :(得分:10)

请检查this answer

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

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

答案 10 :(得分:10)

var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

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

答案 11 :(得分: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)}

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

PS:DebouncergetScrollXYgetDocHeight不是我写的

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

答案 12 :(得分:3)

如果有人想要一个普通的 JS 解决方案并且需要检测用户何时滚动到 <div> 的底部,我设法通过使用这些代码行来实现它

window.addEventListener("scroll", () => {
    var offset = element.getBoundingClientRect().top - element.offsetParent.getBoundingClientRect().top;
    const top = window.pageYOffset + window.innerHeight - offset;

    if (top === element.scrollHeight) {
        console.log("bottom");
    }
}, { passive: false });

答案 13 :(得分:3)

如果滚动到最底端,请尝试使用此匹配条件

if ($(this)[0].scrollHeight - $(this).scrollTop() == 
    $(this).outerHeight()) {

    //code for your custom logic

}

答案 14 :(得分:3)

您可以尝试以下代码,

$("#dashboard-scroll").scroll(function(){
    var ele = document.getElementById('dashboard-scroll');
    if(ele.scrollHeight - ele.scrollTop === ele.clientHeight){
       console.log('at the bottom of the scroll');
    }
});

答案 15 :(得分:3)

尼克回答它很好,但是你会在滚动时重复自己的功能,或者如果用户有窗口缩放则根本不会工作。我想出了一个简单的解决方法,只需数学。在第一个高度,它就像假设的那样工作。

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

答案 16 :(得分:2)

使用Intersection Observer而不是监听滚动事件,inexpensive用于检查最后一个元素在视口上是否可见(这意味着用户已滚动到底部)。带有polyfill的IE7也支持它。

var observer = new IntersectionObserver(function(entries){
   if(entries[0].isIntersecting === true)
      console.log("Scrolled to the bottom");
   else
      console.log("Not on the bottom");
}, {
   root:document.querySelector('#scrollContainer'),
   threshold:1 // Trigger only when whole element was visible
});

observer.observe(document.querySelector('#scrollContainer').lastElementChild);
#scrollContainer{
  height: 100px;
  overflow: hidden scroll;
}
<div id="scrollContainer">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div>
  <div>Item 6</div>
  <div>Item 7</div>
  <div>Item 8</div>
  <div>Item 9</div>
  <div>Item 10</div>
</div>

答案 17 :(得分:1)

所有这些解决方案对我和Firefox和Chrome都不起作用,因此我使用Miles O'Keefemeder omuraliev中的自定义函数,如下所示:

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
    );
}

function getWindowSize()
{
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  return [myWidth, myHeight];
}

$(window).scroll(function()
{
    if($(window).scrollTop() + getWindowSize()[1] == getDocHeight())
    {
        alert("bottom!");
    }
});

答案 18 :(得分:1)

我在普通js中的解决方案:

let el=document.getElementById('el');
el.addEventListener('scroll', function(e) {
    if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) {
        alert('Bottom');
    }
});
#el{
  width:400px;
  height:100px;
  overflow-y:scroll;
}
<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>

答案 19 :(得分:1)

当检查可滚动的元素(即不是window)时,这会给出准确的结果:

// `element` is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
    // Element scrolled to bottom

offsetHeight应该给出元素的实际可见高度(包括填充,边距,滚动条),而scrollHeight是<包括不可见(溢出)区域的元素的strong>整个高度。

jQuery的{​​{1}}应该得到与JS的.outerHeight()类似的结果- .offsetHeight的MDN中的文档尚不清楚其跨浏览器的支持。为了涵盖更多选项,这是更完整的:

offsetHeight

答案 20 :(得分:1)

让我在没有JQuery的情况下展示approch。简单的JS功能:

function isVisible(elem) {
  var coords = elem.getBoundingClientRect();
  var topVisible = coords.top > 0 && coords.top < 0;
  var bottomVisible = coords.bottom < shift && coords.bottom > 0;
  return topVisible || bottomVisible;
}

如何使用它的简短示例:

var img = document.getElementById("pic1");
    if (isVisible(img)) { img.style.opacity = "1.00";  }

答案 21 :(得分:0)

停止反复提醒尼克的回答

ScrollActivate();

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

答案 22 :(得分:0)

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

{{1}}

}

答案 23 :(得分:0)

这是我的两分钱,因为被接受的答案对我不起作用。

var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;

答案 24 :(得分:0)

如果您致电$(window).height()

,则Chrome浏览器会显示整个页面的高度

相反,使用window.innerHeight来获取窗口的高度。 必要的检查应该是:

if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
    console.log("reached bottom!");
}

答案 25 :(得分:0)

显然对我有用的是“身体”而不是“窗口”,像这样:

$('body').scroll(function() {


 if($('body').scrollTop() + $('body').height() == $(document).height()) {
     //alert at buttom
 }
 });

出于跨浏览器兼容性的考虑,使用:

  function getheight(){
    var doc = document;
    return  Math.max(
        doc.body.scrollHeight, doc.documentElement.scrollHeight,
        doc.body.offsetHeight, doc.documentElement.offsetHeight,
        doc.body.clientHeight, doc.documentElement.clientHeight

        );
   }

然后调用$ getheight()函数代替$(document).height()

$('body').scroll(function() {


   if($('body').scrollTop() + $('body').height() == getheight()  ) {
     //alert at bottom
 }
});

用于近乎底部使用:

$('body').scroll(function() {


if($('body').scrollTop() + $('body').height() > getheight() -100 ) {
    //alert near bottom
 }
 });

答案 26 :(得分:0)

许多其他解决方案对我不起作用,因为滚动到底部时,我的div触发了两次警报,而向上移动时,它也向上触发了几个像素,所以解决方案是:

        $('#your-div').on('resize scroll', function()
        {
            if ($(this).scrollTop() +
                $(this).innerHeight() >=
                $(this)[0].scrollHeight + 10) {

                alert('reached bottom!');
            }
        });

答案 27 :(得分:0)

我使用此测试来检测到达底部的滚动: event.target.scrollTop === event.target.scrollHeight - event.target.offsetHeight

答案 28 :(得分:0)

Safari 可以滚动到页面底部,这会导致我们的应用程序出现错误。使用 >= 而不是 === 解决这个问题。

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