【问题标题】:Do Javascript mousemove event handlers block mousemove events?Javascript mousemove 事件处理程序会阻止 mousemove 事件吗?
【发布时间】:2014-07-11 02:49:48
【问题描述】:

如果我有一个密集的mousemove 处理程序

window.moveEventCounter = 0;
window.addEventHandler("mousemove", function(e) {
  for (var i = 0; i < 100; i++) {
    console.log(i);
  }
  window.moveEventCounter++;
});

当为相同(或类似)鼠标操作注册快速事件处理程序时,处理的 mousemove 事件计数少于事件计数。

我认为这是浏览器引擎很聪明,不会在执行繁重的情况下过度填充事件队列,但这不是我的预期。

浏览器丢弃(或不发出)mousemove 事件的策略是什么? (在 Firefox 30 上观察到此行为)

【问题讨论】:

  • 你怎么能注意到一个事件被“丢弃”了?如果不是某些事件被丢弃,而是发出的事件更少,该怎么办?
  • 我比较了两种情况下相同鼠标操作后的事件计数。我确实感觉“发出”或分派的事件更少了——但在这种情况下,限制它的是与 Firefox 的交互性。

标签: javascript events mousemove


【解决方案1】:

浏览器肯定会“丢弃”一些mousemove 事件,主要是因为它不能只为光标经过的每个像素执行一次你的函数。执行频率取决于浏览器本身:

指针设备移动时的事件频率因实现、设备和平台而异,但应触发多个连续的 mousemove 事件以持续移动指针设备,而不是每个鼠标移动实例的单个事件。 鼓励实施确定最佳频率,以平衡响应能力和性能。

来源:http://www.w3.org/TR/DOM-Level-3-Events/#event-type-mousemove

Firefox 可能只会在最后一个事件完成时触发另一个 mousemove 事件,因为 JavaScript 是单线程的,它不想填满堆栈。您可以说 Firefox 正在“阻止”该事件,但我想说的是 Firefox 触发该事件的频率较低。

【讨论】:

  • "它不想填满堆栈" --- 即使它想要它也不能:-)
  • 这正是我正在寻找的答案。我总是可以查看 Firefox 源代码以了解它们的确切用途。
【解决方案2】:

众所周知 - javascript 本质上是单线程的。

这意味着当执行 js 代码时 - 浏览器冻结。这意味着您在那一刻在浏览器中“做”的任何事情 - 都不会被它处理,因为浏览器应用程序对交互没有响应。

这意味着它不是丢弃事件,而是发出更少的事件,因为现在浏览器花费更多时间执行 JS 而不是处理您的输入。

【讨论】:

  • 您的措辞似乎暗示 JS 执行阻止了 mousemove 事件的发出 - 这通常不是真的。例如:window.addEventListener("mousemove", function(e) {console.log(e)}); while (true) {}; 仍然记录移动事件。浏览器何时决定对鼠标移动“闭上耳朵”?
  • @jameh:我想知道你是如何测试这个的。我没有看到任何日志,浏览器立即冻结。
  • @jameh - mousemove 永远不会记录任何内容,因为 while 正在阻止它。 (除非你创建另一个线程..啊哼,工人)
  • 在 Firefox 控制台中输入它,在 DOM 上快速移动鼠标,在“无响应脚本”对话框打开之前从窗口中退出鼠标,单个 mousemove 事件会记录到控制台弹出对话框。
猜你喜欢
  • 1970-01-01
  • 2012-10-29
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多