You don't need scroll events for this, you can do this with Intersection Observer API (IO) . IO was created to solve problems like yours, to react when elements are getting visible or intersecting with each other in the viewport (or with each other).
First you would define the options for the IO:
let options = {
rootMargin: '0px',
threshold: 1.0
}
After the options are defined you say which elements you want to observe:
const elements = document.querySelectorAll('.revealedBox');
As a last step you have to define what happens once an element comes into view and bind it to the elements you defined:
const intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
// when element's is in viewport,
// do something with it!
if (entry.intersectionRatio > 0) {
animate(entry.target); // example: call an "animate" function if you need to animate the element that's getting into view.
// Just do whatever you want with the element here
console.log(entry.target);
// remove observer after animation (if it is no longer needed).
// remove this line if you want to continue observing this element.
observer.unobserve(entry.target);
}
});
});
elements.forEach((element) => intersectionObserver.observe(element));
If you need to support older browsers than use this (official) polyfill from w3c, it recreates intersection observer with listening to scroll events. So it will still be slower on older browsers, nothing you can do about it here. But on newer ones there will be an increase in performance.
Here is a full example of how to animate an element once you scroll it into view. (Scroll all the way down to see it in action)