IntersectionObserver Example

Using IntersectionObserver to implement a infinite scroller without having to rely on scroll events. A sentinel element triggers the loading of additional elements once it comes into view and is being recycled after the new elements have been attached to the list.

by Paco86

HTML

<div id="scroller">
  <div id="sentinel"></div>
</div>

CSS

body {
  padding: 1em;
}

.item {
  background: #FFF;
  border: 1px solid #666;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#sentinel {
  width: 1px;
  height: 1px;
}

#scroller {
  height: 400px;
  overflow-y: scroll;
}

JavaScript

/* global IntersectionObserver */
var scroller = document.querySelector('#scroller');
var sentinel = document.querySelector('#sentinel');
var counter = 1;

function loadItems(n) {
  for (var i = 0; i < n; i++) {
    var newItem = document.createElement('div');
    newItem.classList.add('item');
    newItem.textContent = 'Item ' + counter++;
    scroller.appendChild(newItem);
  }
}

var intersectionObserver = new IntersectionObserver(entries => {
  // If intersectionRatio is 0, the sentinel is out of view
  // and we do not need to do anything.
  if (entries[0].intersectionRatio <= 0) {
    return;
  }
  loadItems(10);
  // appendChild will move the existing element, so there is no need to
  // remove it first.
  scroller.appendChild(sentinel);
  /* loadItems(5) */;
  /* ChromeSamples.setStatus('Loaded up to item ' + counter) */;
});
intersectionObserver.observe(sentinel);