[英]Toggle visibility of element onblur and onclick
I have a div
element used as a toggle, and a select
element which shall be shown/hidden in the way that:我有一个用作切换的div
元素和一个select
元素,它应该以如下方式显示/隐藏:
(1) When clicking the toggle, the select
shall be shown and focused, if it was hidden (1) 点击切换按钮时, select
应显示并聚焦,如果它被隐藏
(2) When clicking the toggle, the select
shall be hidden, if it was visible (2) 当点击切换开关时, select
应该被隐藏,如果它是可见的
(3) When the select looses focus, it shall be hidden. (3) select失焦时,应隐藏。
Now there is this edge case when the select
has focus and user clicks the toggle -- then both events, onclick
and onblur
, are fired and cancel each other, at least in Firefox:现在,当select
具有焦点并且用户单击切换时,就会出现这种边缘情况——然后两个事件onclick
和onblur
至少在 Z763F7F1AEC350CD1A46238D1D5ZC3 中被触发并相互取消:
<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/ https://jsfiddle.net/2wrxykpd/
I tried checking event.explicitOriginalTarget
in the onblur
function (online hide select
if target of the onblur
event is not the toggle), which would work in Firefox, but not in Chrome.我尝试检查onblur
event.explicitOriginalTarget
中的 event.explicitOriginalTarget (如果onblur
事件的目标不是切换,则在线隐藏select
),这将在 Z763F7F1AEC350CD1A46238D1 中有效
So what would be the proper way to do this?那么这样做的正确方法是什么?
One possibility is to wrap the toggle logic in a setTimeout
(though this introduces a blink): https://jsfiddle.net/1mrynkvh/一种可能性是将切换逻辑包装在setTimeout
中(尽管这会引入闪烁): https://jsfiddle.net/1mrynkvh/
document.getElementById('toggle').onclick = function () {
setTimeout(function () {...}, 0)
};
Another option would be to use onmousedown
or onmouseup
instead of onclick
: https://jsfiddle.net/1mrynkvh/2/另一种选择是使用onmousedown
或onmouseup
代替onclick
: https://jsfiddle.net/1mrynkvh/2/
document.getElementById('toggle').onmouseup = function () {...}
Related: jQuery: focusout triggering before onclick for Ajax suggestion相关: jQuery:Ajax 建议的 onclick 之前触发聚焦
You can bind to focus on the toggle and then check against the 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>
I found a solution myself, also see this related question .我自己找到了解决方案,也看到了这个相关的问题。
The idea is to add mousedown
and mouseup
events to the toggle.这个想法是将mousedown
和mouseup
事件添加到切换中。 Then the order of execution will be那么执行顺序将是
(1) toggle.onmousedown (1)toggle.onmousedown
(2) select.onblur (2) select.onblur
(3) toggle.onmouseup (3)toggle.onmouseup
(4) toggle.onclick (4) 切换。onclick
That is, inside the mousedown
/ mouseup
events we can set and reset an ignore flag;也就是说,在mousedown
/ mouseup
事件中,我们可以设置和重置忽略标志; the flag will then only be set inside the onblur
, in the onclick
it will already have been reset.然后该标志将仅在onblur
内部设置,在onclick
中它已经被重置。
So we got所以我们得到了
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';
}
};
https://jsfiddle.net/ezt0sonj/ https://jsfiddle.net/ezt0sonj/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.