这个问题在这里已经有了答案:如何检测浏览器窗口是否滚动到底部? (21 个回答) 8 个月前关闭。社区在 8 个月前审查了是否重新打开此问题并将其关闭:原始关闭原因未解决
我正在制作一个分页系统(有点像 Facebook),当用户滚动到底部时会加载内容。我想最好的方法是找到用户何时位于页面底部并运行 Ajax 查询以加载更多帖子。
唯一的问题是我不知道如何检查用户是否滚动到页面底部。有任何想法吗?
我正在使用 jQuery,因此请随时提供使用它的答案。
在 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
调整为您想要触发的底部像素。
我不确定为什么还没有发布,但根据 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
在浏览器中得到了广泛的支持,更准确地说是 ie 8,而 clientHeight
和 scrollTop
都得到了大家的支持。即使是 6。这应该是跨浏览器安全的。
var isAtBottom = ( logField.scrollHeight - logField.scrollTop <= logField.clientHeight + 50 );
。这对于仅在已位于底部时自动滚动字段很有用(因此用户可以手动检查实时日志的特定部分而不会丢失其位置等)。
200.181819304947
和 200
)。我添加了一个 Math.floor()
来帮助解决这个问题,但我不知道这有多可靠。
Math.abs(element.scrollHeight - element.scrollTop - element.clientHeight) <= 3.0
(将 3.0 替换为您认为适合您的情况的任何像素容差)。这是要走的路,因为 (A) clientHeight
、scrollTop
和 clientHeight
都是四舍五入的,如果全部对齐,可能会导致 3px 错误,(B) 3 个像素对用户来说几乎不可见,因此当用户“认为”他们位于页面底部时,他们可能会认为您的网站有问题,而实际上并非如此,并且 (C) 某些设备(尤其是无鼠标设备)在滚动时可能会出现奇怪的行为。
Nick 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!");
}
});
min
而不是 max
可能会更好,尤其是在有边距的情况下,以避免意外阻止用户滚动到您认为的页面底部。
除了 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,因为当地址栏位于hidden 窗口高度增加了 60 像素,但使用 $(window).height()
不反映了这种变化,而使用 window.innerHeight
可以。
注意:window.innerHeight
属性还包括水平滚动条的高度(如果已呈现),而 $(window).height()
不包括水平滚动条的高度。这在 Mobile Safari 中不是问题,但可能会在其他浏览器或 Mobile Safari 的未来版本中导致意外行为。对于最常见的用例,将 ==
更改为 >=
可以解决此问题。
详细了解 window.innerHeight
属性 here
这是一个相当简单的方法
const didScrollToBottom = elm.scrollTop + elm.clientHeight == elm.scrollHeight
例子
elm.onscroll = function() {
if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) {
// User has scrolled to the bottom of the element
}
}
其中elm
是从即document.getElementById
检索的元素。
value1 : 1200.1111450195312 value2 : 1200
false
。
请检查this answer
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("bottom");
}
};
您可以执行 footerHeight - document.body.offsetHeight
以查看您是否在页脚附近或到达页脚
这是一段可以帮助您调试代码的代码,我测试了上面的答案,发现它们有问题。我在 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>
可能有一个更简单的解决方案,但我停在它工作的地方
如果您仍然遇到某些流氓浏览器的问题,这里有一些代码可以帮助您调试:
<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 docElement = document.documentElement; var winElement = window
winElement.pageYOffset
,您还可以使用 winElement.scrollY
。
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
它计算滚动条到元素底部的距离。等于 0,如果滚动条已到达底部。
scrollTop
没有四舍五入(可以是小数),所以有时即使滚动到底部,该值也不为 0。
这是我的两分钱:
$('#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');
}
});
$(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight
=> $(this).scrollTop() + $(this).outerHeight(true) >= $(this)[0].scrollHeight
scrollTop
不是四舍五入的(它可以是小数),而 scrollHeight 是四舍五入的。这将产生误报。
这是一个使用 ES 6 和 debounce
的普通 JavaScript 解决方案:
document.addEventListener('scroll', debounce(() => {
if(document.documentElement.scrollHeight === window.pageYOffset + window.innerHeight) {
// Do something
}
}, 500))
function debounce(e,t=300){let u;return(...i)=>{clearTimeout(u),u=setTimeout(()=>{e.apply(this,i)},t)}}
演示: https://jsbin.com/jicikaruta/1/edit?js,output
参考:
滚动高度
pageYOffset
内部高度
去抖
我在纯js中的解决方案:
让 el=document.getElementById('el'); el.addEventListener('scroll', function(e) { if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) { alert('Bottom'); } }); #el{ 宽度:400px;高度:100px;溢出-y:滚动; }
scrollTop
不是四舍五入(它可以是小数),而 scrollHeight 是,所以有时计算将是 > 0。
而不是监听滚动事件,使用 Intersection Observer 是 inexpensive 用于检查最后一个元素是否在视口上可见(这意味着用户被滚动到底部)。它还支持带有 polyfill 的 IE7。
var observer = new IntersectionObserver(function(entries){ if(entries[0].isIntersecting === true) console.log("滚动到底部"); else console.log("不在底部"); } , { root:document.querySelector('#scrollContainer'), threshold:1 // 仅在整个元素可见时触发 }); observer.observe(document.querySelector('#scrollContainer').lastElementChild); #scrollContainer{ 高度:100px;溢出:隐藏滚动; }
.observe(...)
,例如当用户悬停/触摸您的滚动容器时,它不会立即触发。
如果有人想要一个普通的 JavaScript 解决方案并需要检测用户何时滚动到 <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 });
尼克回答得很好,但是如果用户缩放窗口,您将拥有在滚动时重复自己或根本不起作用的功能。我想出了一个简单的解决方法,只是 math.round 第一个高度,它的工作原理和假设一样。
if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
loadPagination();
$(".go-up").css("display","block").show("slow");
}
我用纯 JS 完成了这个非常简单的方法。
function onScroll() {
if (window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight - 50) {
Console.log('Reached bottom')
}
}
window.addEventListener("scroll", onScroll);
所有这些解决方案都不适用于 Firefox 和 Chrome,因此我使用来自 Miles O'Keefe 和 meder 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!");
}
});
你可以试试下面的代码,
$("#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');
}
});
scrollTop
可以是小数,而 scrollHeight
和 clientHeight
不是。
如果滚动到底端,请尝试此匹配条件
if ($(this)[0].scrollHeight - $(this).scrollTop() ==
$(this).outerHeight()) {
//code for your custom logic
}
在检查可滚动的元素(即不是window
)时,这会给出准确的结果:
// `element` is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
// Element scrolled to bottom
offsetHeight
应该给出元素的实际可见高度(包括内边距、边距、和滚动条),而 scrollHeight
是整个元素的高度,包括不可见(溢出)区域。
jQuery
的 .outerHeight()
应该给出与 JS 的 .offsetHeight
相似的结果——MDN 中 offsetHeight
的文档不清楚它的跨浏览器支持。为了涵盖更多选项,这是更完整的:
var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
// scrolled to bottom
}
Math.floor(element.scrollTop) === element.scrollHeight - element.offsetHeight
,如果没有 Math.floor()
,它将无法工作
我用这个测试来检测滚动到底部:event.target.scrollTop === event.target.scrollHeight - event.target.offsetHeight
这是我的两分钱,因为接受的答案对我不起作用。
var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;
如果您调用 $(window).height()
,Google Chrome 会提供页面的完整高度
相反,请使用 window.innerHeight
检索窗口的高度。必要的检查应该是:
if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
console.log("reached bottom!");
}
许多其他解决方案对我不起作用因为在滚动到底部时,我的 div 触发了 2 次警报,并且在向上移动时它也触发了几个像素,所以解决方案是:
$('#your-div').on('resize scroll', function()
{
if ($(this).scrollTop() +
$(this).innerHeight() >=
$(this)[0].scrollHeight + 10) {
alert('reached bottom!');
}
});
Safari 可以滚动到导致我们的应用程序出现错误的页面底部。使用 >=
而不是 ===
解决此问题。
container.scrollTop >= container.scrollHeight - container.clientHeight
这是最简单的方法:
const handleScroll = () => {
if (window.innerHeight + window.pageYOffset >= document.body.offsetHeight) {
console.log('scrolled to the bottom')
}}
window.addEventListener('scroll', handleScroll)
element
底部的通知的讨论。这是 body
底部和 JS 而非 jQuery 的最佳答案。
(2021) 这里的很多答案都涉及对 element
的引用,但如果您只关心整个页面,只需使用:
function isBottom() {
const { scrollHeight, scrollTop, clientHeight } = document.documentElement;
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
return distanceFromBottom < 20; // adjust the number 20 yourself
}
让我展示没有 JQuery 的方法。简单的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"; }
我使用了@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!");
}
});
}
console.log()
而不是 alert 它有时会重复该命令。