而不是监听滚动事件,您应该查看Intersection Observer (IO)使用 IO,您可以对元素何时进入视图(或即将进入视图)/离开视图做出反应。Smashing Magazine 也有一篇很棒的文章,很棒的图片可以帮助你理解它。
您可以针对您的问题执行以下操作:您在内容的末尾添加一个可观察的 div,并且每当该 div 即将进入视图时,您都会加载更多数据以附加到该 div。
这是有关如何执行此操作的教程。请记住,您不必像示例中那样显示“加载”文本,这只是为了让您了解发生了什么。
它归结为以下几点:
首先,您为 IO 定义选项:
let options = {
rootMargin: '50px'
}
let observer = new IntersectionObserver(callback, options);
然后,您必须定义要监视交叉点的元素:
let entries = document.querySelectorAll('.load-more-content'); // example for observing more elements, you can also observe just one.
entries.forEach(entry => {observer.observe(entry);}) // if you observe one, you don't need the forEach part.
最后你需要定义回调函数,一旦观察到的元素进入视野应该发生什么:
const observer = new IntersectionObserver(function (entries, self) {
entries.forEach(entry => {
if (entry.isIntersecting) {
// load more content
}
});
}, config);
一个简单的示例,每当您滚动到内容 div 的底部时,都会附加另一个 div。此示例中没有涉及 ajax,一旦您的 ajax 调用中没有更多数据要附加,您可能希望不观察 IO 。
对所有主要浏览器的支持都很好,如果您需要支持 IE,可以使用w3c 的 polyfill 。
const loadMore = document.querySelector('.load-more-content');
const config = {
rootMargin: '50px',
threshold: [.2, .9]
};
const observer = new IntersectionObserver(function (entries, self) {
entries.forEach(entry => {
if (entry.isIntersecting) {
var content = document.querySelector('.my-content');
content.innerHTML = content.innerHTML + '<div class="my-content"> More was "loaded"</div>';
}
});
}, config);
observer.observe(loadMore);
header,
footer {
height: 10vh;
background: pink;
}
.wrapper {
height: 80vh;
overflow: auto;
}
.my-content {
min-height: 150vh;
}
<header> Some content </header>
<div class="wrapper">
<div class="my-content">
<p> Lorem Ipsum </p>
</div>
<div class="load-more-content">
<!-- Whenever this div comes into view, we load more -->
</div>
</div>
<footer>Content </footer>