检查用户是否滚动到底部
我正在制作一个分页系统(有点像Facebook),当用户滚动到底部时,内容加载。 我想最好的办法是find用户在页面底部并运行ajax查询来加载更多的post。
唯一的问题是我不知道如何检查用户是否用jQuery滚动到页面底部。 有任何想法吗?
我需要find一种方法来检查用户何时滚动到页面的底部与jQuery。
在window
上使用.scroll()
事件,如下所示:
$(window).scroll(function() { if($(window).scrollTop() + $(window).height() == $(document).height()) { alert("bottom!"); } });
你可以在这里testing它 ,这需要窗口的顶部滚动,所以向下滚动多less,添加可见窗口的高度,并检查是否等于整个内容( document
)的高度。 如果你想要检查用户是否在底部附近 ,它会看起来像这样:
$(window).scroll(function() { if($(window).scrollTop() + $(window).height() > $(document).height() - 100) { alert("near bottom!"); } });
你可以在这里testing这个版本 ,只要将它调整到你想要触发的底部的任何像素即可。
尼克Craver的答案正常工作,免除$(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!"); } });
我不完全确定为什么这还没有发布,但根据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到更精确,而clientHeight
和scrollTop
都支持大家。 即使ie 6.这应该是跨浏览器的安全。
对于那些使用Nick解决scheme并重复发出警报/事件的人,可以在警报示例上面添加一行代码:
$(window).scroll(function() { if($(window).scrollTop() + $(window).height() > $(document).height() - 100) { $(window).unbind('scroll'); alert("near bottom!"); } });
这意味着代码只会在您第一次在文档底部的100像素以内触发。 如果您向后滚动,然后再向下滚动,则此操作不会重复,取决于您使用的是Nick的代码,这可能有用也可能不会有用。
除了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); }
Nick Craver的答案需要稍作修改才能在iOS 6 Safari Mobile上工作,应该是:
$(window).scroll(function() { if($(window).scrollTop() + window.innerHeight == $(document).height()) { alert("bottom!"); } });
改变$(window).height()为window.innerHeight应该这样做,因为当地址栏被隐藏时,窗口的高度增加了60px,但是使用$(window).height()
并不反映这个改变。 window.innerHeight
。
注意 : window.innerHeight
属性还包含水平滚动条的高度(如果它被渲染的话),不同于$(window).height()
,它不包括水平滚动条的高度。 这在Mobile Safari中不是问题,但可能会在其他浏览器或未来版本的Mobile Safari中引起意外的行为。 将==
更改为>=
可以解决这个最常见的用例。
阅读更多关于window.innerHeight
属性
这里有一段代码会帮助你debugging你的代码,我testing了上面的答案,发现它们是错误的。 我已经在Chrome,IE,Firefox,iPad(Safari)上testing了以下内容。 我没有其他人安装testing…
<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>
可能有一个更简单的解决scheme,但我停在了IT工作的地步
如果你仍然有一些stream氓浏览器的问题,这里有一些代码可以帮助你debugging:
<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;">
我希望这会节省一些时间。
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
它计算距离滚动条到元素的底部。 等于0,如果滚动条已达到底部。
这是一个相当简单的方法:
elm.onscroll = function() { if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) //User has scrolled to the bottom of the element }
这是我的两分钱:
$('#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'); } });
请检查这个答案
window.onscroll = function(ev) { if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { console.log("bottom"); } };
你可以做footerHeight - document.body.offsetHeight
,看看你是在附近的页脚还是到达了页脚
让我看看没有JQuery。 简单的JSfunction:
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"; }
纯JS与跨浏览器和反弹 (相当不错的性能 )
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: getDocHeight
, getScrollXY
, getDocHeight
不是我写的
我只是展示它的工作,以及我将如何做
尼克答得好,但你会有滚动时重复自己的function,或者根本用不了,如果用户有窗口放大。 我想出了一个简单的解决方法,只是第一个高度的math,它就像假设一样工作。
if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){ loadPagination(); $(".go-up").css("display","block").show("slow"); }
我使用@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(); } }
}
停止重复提醒尼克的答案
ScrollActivate(); function ScrollActivate() { $(window).on("scroll", function () { if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) { $(window).off("scroll"); alert("near bottom!"); } }); }