不同浏览器中模糊事件的不同行为

Joh*_*pit 11 javascript focus cross-browser blur dom-events

考虑这个例子,我有2个输入字段:

<input id="a" />
<input id="b" style="display: none" />
Run Code Online (Sandbox Code Playgroud)

并考虑以下JavaScript,这是尝试这样做:

显示#b只有当#a具有焦点,并隐藏#b每当#a失去焦点,除非#a其重点丧失#b.

$("#a").focus(function() {
    $("#b").show();
});

$("#a, #b").blur(function() {
    $("#b").hide();
});

$("#b").focus(function(){
    $("#b").show();
});
Run Code Online (Sandbox Code Playgroud)

$("#a").focus(function() {
  $("#b").show();
});

$("#a, #b").blur(function() {
  $("#b").hide();
});

$("#b").focus(function() {
  $("#b").show();
});
Run Code Online (Sandbox Code Playgroud)
#b {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)
<input id="a" value=a>
<input id="b" value=b>
<br/>^ focus on the input
Run Code Online (Sandbox Code Playgroud)

上面的代码是不正确的,因为$("#b").focus()永远不会被触发,因为一旦#a失去焦点,#b就会被隐藏.在Firefox(版本24.6.0)中观察到此预期行为.

但在Chrome(版本35.0)中,代码似乎运行不正确(或正确!?).

很明显,该b.focus 活动仍在Chrome中注册.为什么此事件在Chrome中注册,而在Firefox中注册?


更新

正如raina77ow所指出的那样:

  • 在Chrome中,在我们放置光标后b,a首先触发模糊,然后对焦bb保持可见.
  • 在Firefox中,焦点b不会被触发,因此b变得不可见.
  • 然而,在IE10中,以某种方式关注于bIS被触发,但是b立即变得不可见,因为模糊在b之后被触发.

这是一个不使用jQuery的小提琴,产生相同的行为.

Nat*_*ami 9

如您所知,问题是不同的浏览器选择以不同的顺序调用事件处理程序.一种解决方案是通过将计时器设置为0毫秒,然后检查字段以查看哪些(如果有的话)被聚焦来为其他事件提供触发的机会.

a.onfocus = function() {show(b);};

a.onblur = function() {
    setTimeout(function() {
        //if neither filed is focused
        if(document.activeElement !== b && document.activeElement !== a){
            hide(b);
        }
            }, 0);
};

//same action as for a
b.onblur = a.onblur;
Run Code Online (Sandbox Code Playgroud)

在Chrome,Firefox,Internet Explorer和Safari中测试过.在JSFiddle.net上查看完整的工作示例(小提琴的编辑版本).

  • setTimeout(function(){})类似于下一个tick,是一个非常糟糕的实践,用于控制程序代码(如果没有按目的完成,例如,给程序一个呼吸来执行下一个排队任务).只是尝试在FOR循环中多次调用blur/unblur(假设为1000),你会发现异步行为会破坏你的代码流 (2认同)