IntersectObserver
by rough cheap
HTML
<div class="obox">
<div class="vertical">
Welcome to <strong>The Box1!</strong>
</div>
</div>
<div class="obox">
<div class="vertical">
Welcome to <strong>The Box1!</strong>
</div>
</div>
<div class="obox">
<div class="vertical">
Welcome to <strong>The Box1!</strong>
</div>
</div>
CSS
.obox {
background-color: rgba(40, 40, 190, 255);
border: 4px solid rgb(29, 29, 120);
transition: background-color 1s, border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
margin-top: 1000px;
margin-bottom: 1000px;
}
.vertical {
color: white;
font: 16px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(29, 29, 120);
text-align: center;
padding: 20px;
}
JavaScript
(function() {
let boxElements;
let observers = [];
let prevRatios = {};
window.addEventListener('load', (e) => {
boxElements = document.getElementsByClassName('obox');
createObserver();
}, false);
function createObserver() {
let observer;
let options = {
root: null,
rootMargin: '0px',
threshold: buildThresholdList(20)
};
for (let i = 0; i < boxElements.length; i++) {
boxElements.item(i).id = `obox-${i}`, prevRatios[boxElements.item(i).id] = 0.0;
observers[i] = new IntersectionObserver(intersectionHandler, options);
observers[i].observe(boxElements.item(i));
}
}
function buildThresholdList(numSteps) {
let thresholds = [];
for (let i = 1.0; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
function intersectionHandler(entries, observer) {
entries.forEach((entry) => {
let ratio = entry.intersectionRatio;
let prevRatio = prevRatios[entry.target.id];
entry.target.children[0].innerHTML = `Prev: ${prevRatio}<br> Current: ${ratio}`;
prevRatios[entry.target.id] = ratio;
});
}
})();