在我的网站上,当一个相关的内容框可见时,它应该被动画到视口中。
我正在尝试通过CSS和JavaScript尽可能提高我的动画效果,这样它就不会对滚动性能产生负面影响。
虽然CSS部分很简单(使用转换,将改变,包含),但我在使用window.requestAnimationFrame
时遇到了一些麻烦。
我是否应该仅在将类添加到元素时使用它,或者在调用函数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;
}
答案 0 :(得分:1)
不要不那样使用它......
结合所有这些以及你得到的是在下一次屏幕刷新之前多次调用堆栈中的相同函数。
相反,您似乎想要的是防止滚动事件在无用时触发。这被称为油门功能,你离它有点远。
以下是使用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
};
}
}
你可以这样使用:
window.addEventListener('scroll', throttle(yourScrollCallback));
答案 1 :(得分:1)
requestAnimationFrame
returns a non-zero long
可用于取消您的请求,因此,您可以使用以下更简单的方法来防止多个处理程序堆积,而不是编写自己的节流实现:
let currentRequest;
document.addEventListener('scroll', function () {
cancelAnimationFrame(currentRequest);
currentRequest = requestAnimationFrame(handleScroll);
});