我认为这在文章中解释得很好。
我们还能做什么?一方面,我们一直在运行 requestAnimationFrame,如果我们不只是滚动,那是没有必要的,因为什么都不会改变。为了解决这个问题,我们让 onScroll 启动 requestAnimationFrame
现在,每当我们滚动时,我们都会尝试调用 requestAnimationFrame,但如果已经请求了一个,我们就不会启动另一个。这是一个重要的优化,因为浏览器将堆叠所有重复的 rAF 请求,我们将回到更新调用超过我们需要的情况。
由于这个设置,我们不再需要在更新顶部调用 requestAnimationFrame,因为我们知道它只会在一个或多个滚动事件发生时被请求。我们也不再需要底部的启动电话,所以让我们相应地更新:
var latestKnownScrollY = 0,
ticking = false;
function onScroll() {
latestKnownScrollY = window.scrollY;
if (!ticking) {
requestAnimationFrame(update);
}
ticking = true;
}
function update() {
ticking = false; // reset the tick so we can capture the next onScroll
var currentScrollY = latestKnownScrollY;
// Do visibilty logic and animation here
}
所以,“不管用户是否继续移动”并不是真的。update
仅在滚动期间(或之后)调用,并且以浏览器选择的帧速率而不是每秒数百个事件的速率调用。