什么导致无法检测到纯JavaScript中滚动到HTML元素底部

什么导致无法检测到纯JavaScript中滚动到HTML元素底部

本文介绍了是什么导致无法检测到纯JavaScript中滚动到HTML元素底部的原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究纯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();
  1. 我创建了函数 getLastPost -它获取您的最后一篇帖子(由js添加).

  1. 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元素底部的原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 01:49