On my website, a related content box should be animated into the viewport when it gets visible.
I’m trying to make my animation as efficient as possible through CSS and JavaScript, so that it doesn’t affects scroll performance negatively.
While the CSS part was simple (using transform, will-change, contain), I’m struggling a bit with when to use window.requestAnimationFrame
.
Should I use it only when the class is added to the element or also when the function isScrolledIntoView
is called or even inside isScrolledIntoView
, when the elements position is measured?
var percentVisible = 0.25;
window.addEventListener('scroll', function(){
relatedContent(related, percentVisible);
}
)
function relatedContent(r, pV){
window.requestAnimationFrame(function() {
if(isScrolledIntoView(r, pV)){
window.requestAnimationFrame(function(){
r.classList.add("visible");
}, r)
}
}, r)
}
function isScrolledIntoView(el, percentV) {
var elemTop, elemBottom, elemHeight, overhang, isVisible;
/*window.requestAnimationFrame(
function(){*/
elemTop = el.getBoundingClientRect().top;
elemBottom = el.getBoundingClientRect().bottom;
elemHeight = el.getBoundingClientRect().height;
/*}
);*/
overhang = elemHeight * (1 - percentV);
isVisible = (elemTop >= -overhang) && (elemBottom <= window.innerHeight + overhang);
return isVisible;
}
No don't use it like that...
Combine all of this and what you get is multiple calls to the same function in a stack, just before the next screen refresh.
Instead, what you seem to want is to prevent your scroll event to fire when not useful. This is called a throttle function, and you're a bit far from it.
Here is a simple throttle implementation using rAF :
That you could use like this :
requestAnimationFrame
returns a non-zerolong
that can be used to cancel your request, so instead of writing your own throttle implementation, you can use the following simpler approach to prevent multiple handlers stacking up: