【问题标题】:div loses focus, when clicked on a child which has focus当单击具有焦点的孩子时,div 失去焦点
【发布时间】:2020-08-05 08:00:06
【问题描述】:

所以,我正在制作一个在显示时关注它的模态。 如果用户在外面点击,我想隐藏它。 我在焦点事件的帮助下实现了这一点。

如果模态本身有一个可聚焦的子对象,模态会失去焦点,我也在下面的代码中处理了它。 onFocusLoss 正确处理了这些情况,但onFocusLoss2 没有正确处理。

function onClickButton() {
  var modal = document.getElementById('modal');
  modal.style.visibility = 'visible';
  modal.focus();
}

function onFocusLoss() {
  var modal = document.getElementById('modal');
  
  setTimeout(function() {
    var activeEl = document.activeElement;
    
    if (modal !== activeEl && !modal.contains(activeEl)) {
      modal.style.visibility = 'hidden';
    }
  }, 0);
}

function onFocusLoss2() {
  var modal = document.getElementById('modal');
  var activeEl = document.activeElement;
  
  if (modal !== activeEl && !modal.contains(activeEl)) {
    modal.style.visibility = 'hidden';
  }
}
#modal {
  position: fixed;
  visibility: hidden;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid red;
}

#modal > div {
  padding: 16px;
}
<button onclick='onClickButton()'>Show Modal</button>
<div id='modal' tabindex='-1' onfocusout='onFocusLoss()'>
  <div>Focus Test</div>
  <div>
    <input>
  </div>
</div>

这就是我假设焦点事件的方式,当模态被聚焦然后我点击内部输入时, 那么首先modal失去焦点,body是活动元素,然后input元素成为活动元素,body失去焦点。

因此,onFocusLoss2 未处理此案的原因可能是因为当时activeEl 是正文,而在onFocusLoss 中,activeEl 是输入。

我的问题是,为什么一种方法有效而另一种方法无效?我想要一个好的技术原因。如果你的回答是它给了足够的时间让输入元素获得焦点,我想知道你怎么能说时间足够并且总是有效的?

不过,我的解决方案是基于 answer

【问题讨论】:

    标签: javascript html css focus


    【解决方案1】:

    不妨改变主意。当模态框获得焦点时,给它下面的元素添加一个点击事件来关闭模态框。

    <body>
      <button onclick='onClickButton()'>Show Modal</button>
      <div id='modal' tabindex='-1'>
        <div>Focus Test</div>
        <div>
          <input>
        </div>
      </div>
    </body>
    
    function onClickButton() {
      const modal = document.getElementById('modal');
      modal.style.visibility = 'visible';
      modal.focus();
      document.body.addEventListener('click', ()=>{
        modal.style.visiable = 'hidden'
      })
    }
    

    别忘了调整 modal 的 z-index 以确保它在 body 上方。

    【讨论】:

      【解决方案2】:

      就像@RiverTwilight 一样,我正在移除焦点需求并简单地添加一个onClick 事件。

      我在您的#modal 中放置了一个&lt;div&gt; 并使#modal 填满整个屏幕,这样您就可以使用不同的动画和其他技术来为您的内容设置动画,只要#modal 没有填充.

      希望你能得到答案。 ✌️

      function onClickButton() {
        var modal = document.getElementById('modal');
        modal.style.visibility = 'visible';
        modal.focus();
      }
      
      function onModalBGClick(e) {
        var modal = document.getElementById('modal');
        var activeEl = e.target;
        
        if (activeEl === modal) {
          modal.style.visibility = 'hidden';
        }
      }
      #modal {
        position: fixed;
        visibility: hidden;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
      }
      
      .modal-inner {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        border: 1px solid red;
      }
      
      #modal > div {
        padding: 16px;
      }
      <button onclick='onClickButton()'>Show Modal</button>
      <div id='modal' onclick='onModalBGClick(event)'>
        <div class="modal-inner">
          <div>Focus Test</div>
          <div>
            <input>
          </div>
        </div>
      </div>

      【讨论】:

        猜你喜欢
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-30
        相关资源
        最近更新 更多