切换元素 onblur 和 onclick 的可见性

Posted

技术标签:

【中文标题】切换元素 onblur 和 onclick 的可见性【英文标题】:Toggle visibility of element onblur and onclick 【发布时间】:2020-02-19 23:32:33 【问题描述】:

我有一个div 元素用作切换开关,还有一个select 元素应以如下方式显示/隐藏:

(1) 当点击切换时,select 将被显示并聚焦,如果它被隐藏了

(2) 当点击切换时,select 应该被隐藏,如果它是可见的

(3) When the select looses focus, it shall be hidden.

select 具有焦点并且用户单击切换时,现在出现了这种边缘情况——然后onclickonblur 这两个事件被触发并相互取消,至少在Firefox 中:

<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/

我尝试在onblur 函数中检查event.explicitOriginalTarget(如果onblur 事件的目标不是切换,则在线隐藏select),这在Firefox 中有效,但在Chrome 中无效。

那么正确的方法是什么?

【问题讨论】:

【参考方案1】:

我自己找到了解决方案,另请参阅related question。

这个想法是将mousedownmouseup 事件添加到切换。那么执行的顺序就是

(1)toggle.onmousedown

(2) 选择.onblur

(3)toggle.onmouseup

(4) 切换.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';
  
;

https://jsfiddle.net/ezt0sonj/

【讨论】:

【参考方案2】:

您可以绑定以关注切换,然后检查相关目标:

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>

【讨论】:

以上是关于切换元素 onblur 和 onclick 的可见性的主要内容,如果未能解决你的问题,请参考以下文章

onclick() 和 onblur() 排序问题

清除文本框值 onclick 并显示 onblur

064_Js常用的五大事件 onclick nochanger onload onsubmit onblur

js常用对象:点击双击onload事件鼠标相关onblur事件和onfocus事件等;通过循环给多个元素添加事件通过addEventListener() 方法 监听事件函数

解决input中智能提示框onblur与onclick冲突的问题

事件(Event)(onclick,onchange,onload,onunload,onfocus,onblur,onselect,onmuse)转载