考虑这个例子 我有2个输入字段:
<input id="a" />
<input id="b" style="display: none" />
并考虑以下JavaScript,这是尝试这样做:
显示 #b
只有当 #a
有焦点和隐藏 #b
每当 #a
失去焦点,除非 #a
失去了它的焦点 #b
。
$("#a").focus(function() {
$("#b").show();
});
$("#a, #b").blur(function() {
$("#b").hide();
});
$("#b").focus(function(){
$("#b").show();
});
$("#a").focus(function() {
$("#b").show();
});
$("#a, #b").blur(function() {
$("#b").hide();
});
$("#b").focus(function() {
$("#b").show();
});
#b {
display: none;
}
<input id="a" value=a>
<input id="b" value=b>
<br/>^ focus on the input
5518
2017-07-08 15:15
起源
嗯,有趣。在这两种情况下,当然, blur 事件必须在之前解雇 focus 一。与Chrome有什么不同 focus 上 #b 仍在注册 - 开火 #b.show()。 - raina77ow
那么,那里实际上有三种不同的行为。在Chrome中,我们将光标放入 b, blur on a 然后先被解雇 focus on b; b 保持可见。在Firefox中, focus on b 没被解雇 b变得无形。然而,在IE10中,不知何故 focus on b 被解雇了,但是 b 立刻变得隐形,如 blur 被解雇了 b 之后。去搞清楚。 - raina77ow
这里的 小提琴 所有控制台输出。 - raina77ow
这里的 讨论 这似乎是相关的。注意那里有两个(略微)连接的问题。简而言之,它似乎是另一个不清楚的规范,在浏览器中实现不同。 - raina77ow
从那里开始:'在Gecko, display:none 元素不会收到关键事件'。 - raina77ow
答案:
如您所知,问题是不同的浏览器选择以不同的顺序调用事件处理程序。一种解决方案是通过设置计时器为其他事件提供触发机会 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;
在Chrome,Firefox,Internet Explorer和Safari中测试过。查看完整的工作示例(小提琴的编辑版本) JSFiddle.net。
9
2017-07-11 10:11
setTimeout(function(){})类似于下一个tick,是一个非常糟糕的实践,用于控制程序代码(如果没有按目的完成,例如,给程序一个呼吸来执行下一个排队任务)。只是尝试在FOR循环中多次调用blur / unblur(假设为1000),你会发现异步行为会破坏你的代码流 - igorpavlov
我同意 - 问题是程序 不 需要一口气来执行下一个排队的任务,这是允许的 b 要关注的元素。是否有更好的Java相当于 Thread.yield()? - Nateowami
在隐藏b之前,您可以使用extravarible来检查b是否聚焦。它适用于IE,Chrome和Firefox。我没有任何其他浏览器。你可以检查一下。
var focusedB = false;
$("#a").focus(function(){
$("#b").show();
});
//if b is focused by pressing tab bar.
$("#a").keydown(function(e){
if(e.which === 9){
focusedB = true;
}
});
$("#b").blur(function(){
$("#b").hide();
});
$("#a").blur(function(){
if(focusedB){
focusedB = false;
}else{
$("#b").hide();
}
});
$( "#b" ).mousedown(function() {
focusedB = true;
});
4
2017-07-12 10:41
这里的真正区别不在于jQuery调用的额外变量 mousedown 之前的事件 blur 事件,即使在Firefox中。加 console.log() 你会看到这种情况。 - Nateowami
我认为我们无法改变特定浏览器中的事件顺序,但正如John所说$(“#b”)。focus()永远不会被触发,因为一旦#a失去焦点,#b就会被隐藏。但是在这里我已经在模糊之前进行了mousedown事件,因此我正在使用额外的变量来检查是否隐藏b。它在Firefox中运行良好。 - Indra
根据 whatwg.org的这个档案:
一个元素是 可聚焦 如果用户代理的默认行为允许 它是可聚焦的,或者如果元素是专门可聚焦的,但仅限于 如果元素正在渲染或是画布的后代 表示嵌入内容的元素。
似乎所有的浏览器也没有 visibility:hidden
和 display:none
输入元素可调焦。 以下JavaScript 案例是一个可以关注的元素的测试。
function isFocusable(type) {
var element = document.getElementById(type);
result += type + ' is';
try {
element.focus();
if (element != document.activeElement)
result += ' not';
} catch (e) {
result += ' not (error thrown)';
}
result += ' focusable<br>';
}
var result = '';
function isFocusable(type) {
var element = document.getElementById(type);
result += type + ' is';
try {
element.focus();
if (element != document.activeElement)
result += ' not';
} catch (e) {
result += ' not (error thrown)';
}
result += ' focusable<br>';
}
isFocusable('text');
isFocusable('hidden');
isFocusable('disabled');
isFocusable('readonly');
isFocusable('visiblity-hidden');
isFocusable('display-none');
isFocusable('div-hidden');
document.getElementById('browser-version').innerHTML = navigator.userAgent;
document.getElementById('logger').innerHTML += result;
<input id=text type=""></input>
<input id=hidden type="hidden"></input>
<input id=disabled disabled></input>
<input id=readonly readonly></input>
<input id=visiblity-hidden style="visibility:hidden"></input>
<input id=display-none style="display:none"></input>
<div id=div-hidden sytle="visibility:hidden" tabindex=1>
</input>
<div id=browser-version></div>
<div id=logger></div>
这是Firefox 34.0.5和Chrome 39.0.2的输出
Gecko/20100101 Firefox/34.0
text is focusable
hidden is not focusable
disabled is not focusable
readonly is focusable
visiblity-hidden is not focusable
display-none is not focusable
div-hidden is focusable
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
text is focusable
hidden is not focusable
disabled is not focusable
readonly is focusable
visiblity-hidden is not focusable
display-none is not focusable
div-hidden is focusable
0
2017-12-18 21:14