问题描述
我正在研究纯JavaScript无限滚动.
I am working on a pure JavaScript infinite scroll.
我有4个帖子列表.当我到达容器底部时,我尝试加载更多帖子(原始"帖子的克隆).
I have a 4 list of posts. I am trying to load more posts (clones of the "original" ones) when I reach the bottom of the container.
class InfiniteScroll {
constructor() {
this.observer = null;
this.isLoading = false;
this.postsContainer = document.querySelector('#postsContainer');
this.postsArary = postsContainer.querySelectorAll('.post');
this.hasNextPage = this.postsContainer?.dataset?.hasNextPage === 'true';
this.currentPage = this.postsContainer?.dataset?.currentPage;
this.nextPage = this.hasNextPage ? this.currentPage + 1 : null;
}
loadMorePosts() {
if (this.hasNextPage) {
this.postsArary.forEach(item => {
let postClone = item.cloneNode(true);
this.postsContainer.appendChild(postClone);
});
}
}
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
this.loadMorePosts();
}
});
});
this.observer.observe(this.postsContainer);
}
}
init() {
this.bindLoadMoreObserver();
}
}
const infiniteScroll = new InfiniteScroll();
infiniteScroll.init();
body, body * {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.post {
margin: 20px;
padding: 15px;
border: 1px solid #ccc;
border-radius: 5px;
}
p {
line-height: 1.5;
}
<div id="postsContainer" data-has-next-page="true" data-current-page="1" data-max-count="11">
<div class="post">
<h2>Title 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?</p>
</div>
<div class="post">
<h2>Title 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?</p>
</div>
<div class="post">
<h2>Title 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?</p>
</div>
<div class="post">
<h2>Title 4</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?</p>
</div>
</div>
帖子克隆,而不是滚动到最后一个帖子后附加到容器中,而是在页面加载时附加.
The post clones, instead of being appended to the container after scrolling to the last post, are appended when the page loads.
我不想使用 rootMargin
,因为它似乎并不通用.
I do not want to use rootMargin
, because it does not seem versatile.
我在做什么错了?
推荐答案
好的,也许它可以帮助某人:
Ok, maybe it will help someone:
class InfiniteScroll {
constructor() {
this.observer = null;
this.isLoading = false;
this.postsContainer = document.querySelector('#postsContainer');
this.postsArary = postsContainer.querySelectorAll('.post');
this.hasNextPage = this.postsContainer ? .dataset ? .hasNextPage === 'true';
this.currentPage = this.postsContainer ? .dataset ? .currentPage;
this.nextPage = this.hasNextPage ? this.currentPage + 1 : null;
}
loadMorePosts() {
if (this.hasNextPage) {
this.postsArary.forEach(item => {
let postClone = item.cloneNode(true);
this.postsContainer.appendChild(postClone);
});
} else {
if (this.observer) this.observe.disconnect();
}
}
getLastPost() {
const allPosts = [...this.postsContainer.querySelectorAll('.post')];
return allPosts[allPosts.length - 1];
}
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
observer.unobserve(entry.target);
this.loadMorePosts();
observer.observe(this.getLastPost());
}
});
});
this.observer.observe(this.getLastPost());
}
}
init() {
this.bindLoadMoreObserver();
}
}
const infiniteScroll = new InfiniteScroll();
infiniteScroll.init();
-
我创建了函数
getLastPost
-它获取您的最后一篇帖子(由js添加).
I made the function
getLastPost
- it gets the last of your posts (included added by js).
我观察了最后一个帖子,而不是整个容器
I observe last post, not the whole container
然后,当该项目与之相交时,我做了两件事:取消观察当前的entry元素,然后在添加新元素之后,我观察到最后一个帖子-因此这将是js添加的最后一个帖子.
then when this item is intersecting I made 2 things: unobserve current entry element, then after appending new elements I observe the last post- so this will be very last post, added by js.
作为loadMorePosts中的奖励我看到您希望仅在有下一页可用时添加帖子.但是当您的IO仍然无法正常工作,但不是必需的(性能)时.所以...断开连接-断开连接正在杀死IO进程,也无法观察该IO中的所有元素.
as bonus in loadMorePosts I saw that you want add posts just when there is next page available.But when not your IO still works, but it's not neccesary (performance). So... disconnect-- disonnect is killing IO process also unobserve all elements in this IO.
这篇关于是什么导致无法检测到纯JavaScript中滚动到HTML元素底部的原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!