JSFiddle - React, Tailwind, and code Playground

by Marco Abate

HTML

<div class="component" data-component="first">Component</div>
<div class="component" data-component="second">Component</div>
<div class="component" data-component="third">Component</div>
<div class="component" data-component="fourth">Component</div>
<div class="component" data-component="fifth">Component</div>
<div class="component" data-component="first">Component</div>
<div class="component" data-component="second">Component</div>
<div class="component" data-component="third">Component</div>
<div class="component" data-component="fourth">Component</div>
<div class="component" data-component="fifth">Component</div>
<div class="component" data-component="first">Component</div>
<div class="component" data-component="second">Component</div>
<div class="component" data-component="third">Component</div>
<div class="component" data-component="fourth">Component</div>
<div class="component" data-component="fifth">Component</div>

SCSS

.component {
	height: 400px;
	background-color: red;
	display: flex;
	justify-content: center;
	align-items: center;
	color: white;
	&.loaded {
		background-color: green;
	}
}

JavaScript

const elements = document.querySelectorAll('[data-component]');

let observers = [];

const intersectionCallback = (entries) => {
	entries.forEach((entry) => {
		console.log('observing');
		if (entry.isIntersecting) {
			let elem = entry.target;
			elem.classList.add('loaded')
			const observerIndex = elem.dataset.observerIndex
			observers[observerIndex].disconnect();
		}
	});
};

elements.forEach((element, i) => {
	element.dataset.observerIndex = i;
	observers[i] = new IntersectionObserver(intersectionCallback, {
		root: null,
		rootMargin: "-100px",
	});

	observers[i].observe(element);
})