对于以下测试用例(我将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请求运行的时间。
答案 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毫秒左右)的顺序为
“ blur”和“ timer”事件是针对输入字段及其setTimeout()
回调的。如果我将超时间隔延长,例如150ms左右,那么我得到
我认为这是有道理的:“ mousedown”和“ mouseup”事件是由您与鼠标按钮的实际物理交互驱动的。直到收到“ mouseup”,“ click”事件才有意义。在“模糊”处理程序中使用短计时器,计时器可以在鼠标通过操作系统等物理传达“向上”事件之前触发。