我正在执行一项任务,其中每当用户滚动或调整屏幕大小时,我都希望重新计算元素的CSS属性。
假设我想实施。进度条,并根据窗口中的滚动位置报告进度
<div class='progress-bar-wrap'>
<div class='progress-bar-progress'></div>
</div>
function updateScrollProgress () {
this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}
我试图钩住滚动和调整大小的事件,但这似乎效果不佳。
window.on('scroll', updateScrollProgress)
window.on('resize', updateScrollProgress)
我尝试了滚动并调整事件处理程序的大小以请求requestAnimationFrame
window.on('scroll', function(){window.requestAnimationFrame( updateScrollProgress))
window.on('resize', function(){window.requestAnimationFrame( updateScrollProgress))
在大多数浏览器中都经历了巨大的改进,但是偶尔还是比较落后。
我尝试从requestAnimationFrame处理程序请求另一个框架:
function updateScrollProgress () {
window.requestAnimationFrame( updateScrollProgress)
this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}
这完全消除了滞后效应,但是即使不需要重新计算,也要无休止地循环调用此方法。
是否有一种方法可以在浏览器决定绘制元素之前挂接处理程序,以便为属性提供/设置那些“动态” css值?
答案 0 :(得分:1)
使用requestAnimationFrame
时您正在做什么。如果您已经摆脱了使用它的滞后,则不清楚您为什么说该函数“经常运行”。通常,在这种情况下,“太频繁”的意思是“造成延迟”(通过频繁运行和放慢速度)。如果不是,那么...?
如果您希望处理程序的调用频率降低,则可以对其进行反跳,但是您可能会注意到想要的更改之前延迟(因为已被反跳),这听起来像是您要避免的操作
无论如何,至少到目前为止,requestAnimationFrame
是“就在浏览器渲染框架之前”作业的正确工具。
答案 1 :(得分:0)
通过反跳功能包装事件功能:
有关反跳功能的更多信息,请点击此处:
https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
window.addEventListener('resize', myEfficientFn);