javascript - 为什么这个 requestAnimationFrame debounce 示例不起作用?
问题描述
如果你打开控制台并上下滚动这个例子,你会看到很多次no debounce
。debounced
相反,它应该充当去抖动功能,因此您应该看到 multiple no debounce
for each one debounced
。
这也是它在示例来源的https://gomakethings.com/debouncing-your-javascript-events/中所说的。所以它对他有用,但我无法让它工作。我怎样才能让它像那样工作?
requestAnimationFrame
并且cancelAnimationFrame
在所有主要浏览器中都受支持,因此我使用代码的方式一定有问题。
// Setup a timer
var timeout;
// Listen for resize events
window.addEventListener('scroll', function ( event ) {
console.log( 'no debounce' );
// If there's a timer, cancel it
if (timeout) {
window.cancelAnimationFrame(timeout);
}
// Setup the new requestAnimationFrame()
timeout = window.requestAnimationFrame(function () {
// Run our scroll functions
console.log( 'debounced' );
});
}, false);
Hi, there! Start scrolling.<br><br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
The end.
解决方案
更新:该片段的行为如 Safari 12 中所述。原始文章明确指出:
[...]Firefox 缓慢而明智地触发事件,IE 和 Webkit 完全瘫痪。
Chrome 已经修复了这个问题,表现得更像 Firefox。但是 Safari(至少版本 12,我机器上的那个)仍然会触发大量事件。
我原来的答案是站得住脚的,只是我减少了我的模棱两可。
原来的
该片段是一个非常规的去抖动,旨在防止同一帧上的多个滚动事件。片段的行为绑定到您正在使用的浏览器。我也想象它对 iOS 来说更糟,但没有费心在设备上尝试(主要是因为我无法从我的设备运行片段......)。
如果您查看JavaScript 中的 Debounce — 提高应用程序的性能,您会发现虽然它们的 debounce 代码非常相似,但它包含一个延迟 ( wait
)。这是一种传统的去抖动方法。
// Credit David Walsh (https://davidwalsh.name/javascript-debounce-function)
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function executedFunction() {
var context = this;
var 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);
};
};
问题中的原始代码段防止'scroll'
每帧多次触发,在这种情况下,requestAnimationFrame 被取消并且事件被有效地去抖动。
推荐阅读
- python - 将 HTTP 上传的数据返回到 sanic 服务器
- python - 如何在 Discord.py 中发布公告命令?
- python - 使用通用视图在 Django 中关联对象和用户
- php - 包含 19000 多种产品的 Wordpress 查询
- javascript - 如何在JS和TS中使用map和filter获取字符串数组?
- java - Java 说 0 年是闰年,但 0 年从未存在过
- javascript - 如何生成包含非零元素索引的张量?
- php - Laravel 5.6:在有windows的电脑中获取硬盘序列号并在控制器中使用
- excel - VLookUpFunction VBA - 不返回所需的值
- c# - 在 RichTextBox WPF MVVM 中突出显示电子邮件和电话号码