我有一个div
元素用作切换按钮,一个select
元素应以以下方式显示/隐藏:
((1)单击切换开关时,select
应该显示并聚焦(如果隐藏)
((2)单击切换开关时,select
应该被隐藏,如果它可见]
((3)当选择失去焦点时,它将被隐藏。
[当select
具有焦点并且用户单击切换时,现在会出现这种情况-至少在Firefox中会触发并取消onclick
和onblur
这两个事件:
<div id="toggle">toggle</div>
<div>foobar</div>
<select id="select" multiple>
<option>foo</option>
<option>bar</option>
</select>
document.getElementById('toggle').onclick = function () {
var select = document.getElementById('select');
select.style.display = select.style.display === 'none' ? 'inline' : 'none';
select.focus();
};
document.getElementById('select').onblur = function () {
this.style.display = 'none';
};
https://jsfiddle.net/2wrxykpd/
我尝试在event.explicitOriginalTarget
函数中检查onblur
(如果select
事件的目标不是切换,则在线隐藏onblur
,该功能在Firefox中有效,但在Chrome中不可用。
那么这样做的正确方法是什么?
您可以绑定以专注于切换,然后对照relatedTarget进行检查:
var select = document.getElementById('select');
var toggle = document.getElementById('toggle');
toggle.addEventListener('focus', function (event) {
if (event.relatedTarget !== select) {
var isHidden = select.classList.toggle('hidden')
if (!isHidden) {
select.focus();
}
}
toggle.blur()
});
select.addEventListener('blur', function () {
select.classList.add('hidden')
});
.hidden {
display: none !important;
}
<div>
<button id="toggle">toggle</button>
</div>
<div>
<select id="select" class="hidden" multiple>
<option>foo</option>
<option>bar</option>
</select>
</div>
我自己找到了解决方案,也看到了此related question。
想法是将mousedown
和mouseup
事件添加到切换。然后执行顺序将是
((1)toggle.onmousedown
((2)select.onblur
((3)toggle.onmouseup
((4)toggle.onclick
也就是说,在mousedown
/ mouseup
事件中,我们可以设置和重置忽略标志;那么该标志将仅在onblur
内部设置,在onclick
中将已经被重置。
所以我们得到了
document.getElementById('toggle').onclick = function () {
var select = document.getElementById('select');
select.style.display = select.style.display === 'none' ? 'inline' : 'none';
select.focus();
};
document.getElementById('toggle').onmousedown = function () {
document.getElementById('select').ignoreClickEvent = true;
};
document.getElementById('toggle').onmouseup = function () {
document.getElementById('select').ignoreClickEvent = false;
};
document.getElementById('select').onblur = function () {
if (!this.ignoreClickEvent) {
this.style.display = 'none';
}
};