JSFiddle - React, Tailwind, and code Playground

Intersection Observer Test: one observer for all elements

by Travis Almand

SCSS

.item {
  border: 1px solid rebeccapurple;
  height: 50vh;
  transition: 0.25s;
}
.zero {
  background-color: darken(#F5F5F5, 100%);
}
.one-quarter {
  background-color: darken(#F5F5F5, 75%);
}
.half {
  background-color: darken(#F5F5F5, 50%);
}
.three-quarter {
  background-color: darken(#F5F5F5, 25%);
}
.full {
  background-color: #F5F5F5;
}

JavaScript

console.clear();

var body = document.querySelector('body');
var template = '<div class="item">item</div>';

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: [0, 0.25, 0.5, 0.75, 1]
}

var observer = new IntersectionObserver(callback, options);

function callback (entries, observer) {
	console.log(entries);
	entries.forEach(entry => {
  	var ratio = entry.intersectionRatio;
    var range = '';
  	entry.target.classList.remove('zero', 'one-quarter', 'half', 'three-quarter', 'full');
    
    if (ratio === 0) {
    	range = 'zero';
    } else if (ratio > 0 && ratio <= 0.25) {
    	range = 'one-quarter';
    } else if (ratio > 0.25 && ratio <= 0.5) {
    	range = 'half';
    } else if (ratio > 0.5 && ratio <= 0.75) {
    	range = 'three-quarter';
    } else if (ratio > 0.75 && ratio <= 1) {
    	range = 'full';
    } else {
    	range = '';
    }
    
    entry.target.classList.add(range);
    
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
}

for (var i = 0; i < 100; i++) {
  var item = document.createElement('div');
  item.classList.add('item');
  
  document.body.appendChild(item);
  observer.observe(item);
}