Trying to understand a quirk in intersectionObserver API.
If an observed element is partially on screen but has not met the threshold defined in the options I would expect the call back not to fire, but it does. Trying to understand why or how to prevent it on page load.
function handleIntersect(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
// Should only fire at >= 0.8
console.log(entry, entry.intersectionRatio);
entry.target.classList.add('play');
}
});
}
function createObserver(element) {
let observer;
const options = {
threshold: [0.8]
};
observer = new IntersectionObserver(handleIntersect, options);
observer.observe(element);
}
const waypoints = document.querySelectorAll('.section');
waypoints.forEach(waypoint => {
createObserver(waypoint);
});
Reduced test case: https://codepen.io/WithAnEs/pen/gxZPMK
Notice how the first 2 sections are animated in even though the second section does not meet the 0.8 threshold (console log). The first inclination is to add an intersectionRatio > 0.8 check, but this is a duplicate effort. Also, the ratio reporting is delayed so could be inaccurate enough not to pass this check.
isIntersectingdoesn't depend on thresholds. It istrue, iftargetelement touches or intersectsrootelement. So it's alwaystrueifintersectionRatio > 0.Generally,
callbackis called when conditionintersectionRatio >= your_thresholdis changed. Therefore it can be called with anyintersectionRatiovalue.Moreover, it's always called initially.
Also pay attention that
0.8is just your desired threshold, butobserver.thresholds[0]is actual. Without going into details, they could be different a bit, e.g. in Chrome.