Как правильно записать callback для IntersectionObserver?

На странице сайта, есть контейнер .content_container с динамическим контентом, необходимо сделать так, что если видна (или пользователь докрутил) последние 100px контейнера, то чтобы в этот контейнер добавлялся еще один контент (в примере, вместо контента использую блок .inner-content), и так далее, если снова докрутил, и видно последние 100px контейнера, то снова загружаем в конец контейнера контент.

так должно происходить заданное кол-во раз, пусть будет 5.

введите сюда описание изображения

$(function () {

        var observer_options = {
            root: null,
            rootMargin: '0px',
            threshold: 0
        };
    
        var observer_callback = function(entries, observer) {
              // ....
        };

        var observer = new IntersectionObserver(
        observer_callback,
      observer_options
    );
    
    observer.observe(
        document.querySelector('.content_container')
    );

});
header {
  background: cyan;
  min-height: 100px;
}

.content_container {
    background: rgba(255, 0, 0, 0.3);
    padding: 20px;
}

.inner-content {
  height: 400px;
  margin: 5px;
  background: red;
}

footer {
  background: cyan;
   min-height: 500px;
}
<html>
  <head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  </head>
  <body>
    <header>
       <div>other content</div>
       <p>text two</p>
    </header>
    
    
    <div class="content_container">
        <div class="inner-content"></div>      
      
    </div>
    
    
    
    <footer>
      <p>footer content</p>
    </footer>
  </body>
</html>


Ответы (1 шт):

Автор решения: immitsu

То, что вы хотите реализовать, называется Infinite Scroll, просто добавляется ограничение на кол-во новых элементов.

Если нужно использовать именно IntersectionObserver, то вот:

const container = document.querySelector('.content_container');
const contentBlock = document.querySelector('.inner-content');

function loadItem() {
  const newItem = document.createElement('div');
  newItem.className ='inner-content';
  container.appendChild(newItem);
}

let limiter = 1 // Ограничитель

const intersectionObserver = new IntersectionObserver(entries => {
  if (entries.some(entry => entry.intersectionRatio > 0) && limiter < 5) {
    loadItem();
    container.appendChild(contentBlock);
    limiter += 1;
  }
});

intersectionObserver.observe(contentBlock);

Но, по-моему, лучше это реализовать через отслеживание положения скролла, как отметил @Дмытрык в комментариях к вопросу.

const container = document.querySelector('.content_container');
const contentBlock = document.querySelector('.inner-content');
const pixelsWhenCallFn = 100;

function loadItems(n) {
  const isBottom = (window.innerHeight + window.scrollY) >= container.offsetHeight - pixelsWhenCallFn;
  if (isBottom) {
    for (let i = 0; i < n; i++) {
    const newItem = document.createElement('div');
    newItem.className ='inner-content';
    container.appendChild(newItem);  
    }
  }
}

loadItems(2); // Загрузим, чтобы появился скролл

window.addEventListener('scroll', function(event) {
  loadItems(1);
})
→ Ссылка