【问题标题】:Toggle visibility of element onblur and onclick切换元素 onblur 和 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 中无效。

那么正确的方法是什么?

【问题讨论】:

    标签: javascript onclick event-handling onblur


    【解决方案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>

      【讨论】:

        猜你喜欢
        • 2014-03-13
        • 2012-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多