【问题标题】:Why doesn't this requestAnimationFrame debounce example work? [duplicate]为什么这个 requestAnimationFrame debounce 示例不起作用? [复制]
【发布时间】:2019-10-20 15:50:11
【问题描述】:

如果您打开控制台并上下滚动此示例,您会看到no debounce 后跟debounced 很多次。相反,它应该充当去抖动功能,因此您应该看到多个no debounce 对应每个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.

【问题讨论】:

  • 它seems to work 用你描述的方式给我吗?
  • 对我来说就是这样。就像我在帖子中所说的 you should see multiple no debounce for every one debounced 而不是 1 换 1。
  • 啊,我关注的是你的这篇文章:“你没有看到 debounce,然后 debounced 很多次”,这似乎也没有发生。跨度>
  • 啊,我明白你现在在说什么了——你的意思是你多次看到他们这对,而不是你看到一次没有去抖动后又看到了多次去抖动。在这方面有很多困惑:)
  • FWIW,您链接到的页面上的演示对我来说似乎也一样 - 我看到每个都有一个不断记录。

标签: javascript addeventlistener dom-events requestanimationframe debouncing


【解决方案1】:

更新:sn-p 的行为与 Safari 12 上的描述相同。原始文章明确指出:

[...]Firefox 缓慢而明智地触发该事件,IE 和 Webkit 完全瘫痪。

Chrome 已经修复了这个问题,表现得更像 Firefox。但是 Safari(至少版本 12,我机器上的那个)仍然会触发大量事件。

果然,在 Safari 中尝试并得到了去抖事件: .

我原来的答案是不变的,只是我已经减少了我的模棱两可。

原创

sn-p 是一种非常规的去抖动,旨在防止在同一帧上发生多个滚动事件。 sn-p 的行为与您正在使用的浏览器绑定。我也想这对 iOS 来说更糟,但没有费心在设备上尝试(主要是因为我无法从我的设备运行 sn-ps...)。

如果您查看Debounce in JavaScript — Improve Your Application’s Performance,您会发现虽然它们的去抖动代码非常相似,但它包含一个延迟 (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);
  };
};

问题中的原始 sn-p 防止 'scroll' 每帧被多次触发,在这种情况下,requestAnimationFrame 被取消并且事件被有效地去抖动。

【讨论】:

    猜你喜欢
    • 2020-11-10
    • 2011-04-10
    • 1970-01-01
    • 2018-06-12
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    相关资源
    最近更新 更多