Javascript事件排队:XHR响应模糊在父onclick之前排队

时间:2018-10-31 16:38:18

标签: javascript html html5 dom-events

对于以下测试用例(我将XHR调用替换为setTimeout来表示响应速度非常快的XHR调用)

-I../path/to/subproject/**

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

<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>

我希望setonout事件之前已将父onclick处理程序排队。至少在Chrome中没有。该行为是由标准指定还是与实现有关?我还对始终在超时(或XHR)处理程序之前运行父onclick处理程序的解决方法感兴趣。

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

1 个答案:

答案 0 :(得分:1)

这不一定能解决您的实际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);
});

该代码的作用是按事件实际发生的时间对其进行排序。在单击 之后单击文本并将其聚焦在输入字段上的情况下,具有较短超时(小于100毫秒左右)的顺序为

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

“ blur”和“ timer”事件是针对输入字段及其setTimeout()回调的。如果我将超时间隔延长,例如150ms左右,那么我得到

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

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