[英]60fps: How to use requestAnimationFrame the right way?
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. 我试图通过CSS和JavaScript使动画尽可能高效,以免对滚动性能产生负面影响。
While the CSS part was simple (using transform, will-change, contain), I'm struggling a bit with when to use window.requestAnimationFrame
. 虽然CSS部分很简单(使用transform,will-change,contain),但我在何时使用
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? 我应该仅在将类添加到元素时使用它还是在调用
isScrolledIntoView
函数甚至在isScrolledIntoView
内部时(在测量元素位置时)使用它?
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 : 这是一个使用rAF的简单节流阀实现:
var throttle = function(callback) {
var active = false; // a simple flag
var evt; // to keep track of the last event
var handler = function(){ // fired only when screen has refreshed
active = false; // release our flag
callback(evt);
}
return function handleEvent(e) { // the actual event handler
evt = e; // save our event at each call
if (!active) { // only if we weren't already doing it
active = true; // raise the flag
requestAnimationFrame(handler); // wait for next screen refresh
};
}
}
That you could use like this : 您可以这样使用:
window.addEventListener('scroll', throttle(yourScrollCallback));
requestAnimationFrame
returns a non-zero long
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: requestAnimationFrame
返回一个非零long
requestAnimationFrame
,可用于取消您的请求,因此您可以使用以下更简单的方法来防止多个处理程序堆积,而不是编写自己的节流实现:
let currentRequest;
document.addEventListener('scroll', function () {
cancelAnimationFrame(currentRequest);
currentRequest = requestAnimationFrame(handleScroll);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.