JavaScript 事件队列 : XHR response in blur queued before parent onclick

标签 javascript html dom-events

对于以下测试用例(我用 setTimeout 替换了 XHR 调用,以表示具有非常快响应的 XHR 调用):

<html>
  <body>
     <div onclick="console.log('onclick parent')">
       Event Queue Test:
       <input type=text onblur="console.log('onblur'); setTimeout(function() {console.log('onblur timeout')})"/>
     </div>
   </body>
</html>

如果我单击文本字段,然后单击文本字段前面的文本,我会在 Chrome (v70) 中得到以下输出:

onblur
onblur timeout
onclick parent

我希望父 onclick 处理程序在 setTimeout 事件之前已排队。至少在 Chrome 中,情况并非如此。此行为是由标准指定的还是依赖于实现的?我还对始终让父级 onclick 处理程序在超时(或 XHR)处理程序之前运行的解决方法感兴趣。

在我的实际用例中,这个问题是有问题的,因为不能保证事件按照相同的顺序排队,具体取决于 XHR 请求运行的时间。

最佳答案

这不一定有助于解决您实际的 XHR 问题,但我想我明白发生了什么。为了方便起见,我使用 jQuery 扩展了您的示例代码:

<div class=parent>Label: <input class=field></div>

和 JavaScript:

var $d = $(document);

var t = {
  mousedown: -1,
  mouseup: -1,
  focus: -1,
  click: -1,
  blur: -1,
  timer: -1
};

["mousedown", "mouseup", "focus", "click"].forEach(function(event) {
    $d.on(event, ".parent", function() {
    t[event] = Date.now();
  })
});
$d.on("blur", ".field", function() {
    t.blur = Date.now();
  setTimeout(function() {
    t.timer = Date.now();
  }, 150);
});
$d.on("click", ".parent", function() {
    setTimeout(function() {
    var race = Object.keys(t).sort(function(k1, k2) { return t[k1] - t[k2];});
    console.log("Result: ", race);
    race.forEach(function(key) { t[key] = -1; });
  }, 1000);
});

该代码的作用是按照事件实际发生的时间对事件进行排序。在点击并聚焦在输入字段后点击文本的情况下,超时时间短(小于100ms左右)的订单是

  1. 焦点
  2. 鼠标按下
  3. 模糊
  4. 计时器
  5. 鼠标松开
  6. 点击

“blur”和“timer”事件用于输入字段及其 setTimeout() 回调。如果我将超时间隔设置得更长,例如 150 毫秒左右,那么我会得到

  1. 焦点
  2. 鼠标按下
  3. 模糊
  4. 鼠标松开
  5. 点击
  6. 计时器

我认为,这是有道理的:“mousedown”和“mouseup”事件是由您与鼠标按钮的实际物理交互驱动的。在收到“mouseup”之前,“click”事件没有意义。通过“模糊”处理程序中的短计时器,计时器可以在鼠标通过操作系统等物理传达“向上”事件之前触发。

关于JavaScript 事件队列 : XHR response in blur queued before parent onclick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53088239/

相关文章:

javascript - 让网站的左侧部分随着滚动条自动向下滚动

javascript - 雪花 UDF 和数据加密

javascript - 将变量从 html 内的 JS 代码传递到单独的 JS 代码,不起作用

javascript - 如何将 onClick 事件处理程序添加到 Canvas 元素 (arc)?

javascript - 使用 Angular 页面滚动事件

javascript - 添加事件监听器 Javascript 的问题

javascript - 动态插入的 CSS(通过链接)在框架加载后应用

javascript - LeafletJS 中 React 与真实 DOM 的配合

html - Bootstrap 中的固定内容没有响应

html - 对齐多个 SVG 以创建可扩展容器