我正在制作一个分页系统(有点像Facebook),当用户滚动到底部时,内容就会加载。我认为最好的方法是找到用户在页面底部的时间,然后运行Ajax查询来加载更多的帖子。
唯一的问题是我不知道如何检查用户是否已经滚动到页面的底部。什么好主意吗?
我使用jQuery,所以请随意提供使用它的答案。
我正在制作一个分页系统(有点像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), 或者节流(防止训练者在一段时间内射击一次以上)。
在选择做这些事情时必须非常小心,例如,限制事件可以防止最后一个卷轴发射,这可能会完全击败无限卷轴。
大多数时候,不做这三件事中的任何一件都是完美的,因为仅仅看看我们是否完全滚动是相对便宜的。
其他回答
所有这些解决方案在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!");
}
});
这是我的意见,因为公认的答案对我不起作用。
var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;
许多其他解决方案不适合我,因为在滚动到底部我的div触发警报2次,当向上移动时,它也会触发到几个像素,所以解决方案是:
$('#your-div').on('resize scroll', function()
{
if ($(this).scrollTop() +
$(this).innerHeight() >=
$(this)[0].scrollHeight + 10) {
alert('reached bottom!');
}
});
请检查这个答案
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("bottom");
}
};
你可以执行footerHeight - document.body.offsetHeight来查看你是否接近页脚或到达页脚
我用这个测试来检测滚动到达底部: event.target.scrollTop === event.target.scrollHeight - event.target.offsetHeight