【问题标题】:Close popup if clicking outside it如果在外部单击,则关闭弹出窗口
【发布时间】:2019-08-10 20:03:20
【问题描述】:

我的这段代码显示了一个显示弹出窗口的按钮,我希望用户能够在弹出窗口打开时通过单击它外部来关闭它。

所以我想将方法​​“Close()”分配给检测到外部点击类“.popup”的事件侦听器,现在它只是一个警报。

问题是,当我单击按钮时,即使弹出窗口尚未打开,它也已经开始发出警报,我希望事件侦听器在弹出窗口打开后开始工作,而不是之前。

我们也非常感谢任何关于删除重复代码的建议。

谢谢。

    /* Clean up the URL from '#popup1' in the end */
    history.replaceState(null, null, ' ');
    

    /* Take off the popup from DOM before clicking in case user refresh*/
    let id_popup = document.querySelector('#popup1');
    let popup = id_popup.parentNode
    popup.removeChild(id_popup);

    

    /*Opening the popup*/
    function Open() {
      popup.appendChild(id_popup);
      
      let class_popup = document.querySelector('.popup');
      window.addEventListener('click', function (e) {

        if (!class_popup.contains(e.target)) {
          alert('You\'re clicking outside the popup !') 
        }
      });
    }


    /*Closing the popup*/
    function Close() {
      popup.removeChild(id_popup);
      history.replaceState(null, null, ' ');
    }
  .button {
    font-size: 1em;
    padding: 10px;
    color: #000;
    border: 2px solid #06D85F;
    border-radius: 20px/50px;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.3s ease-out;
  }

  .button:hover {
    background: #06D85F;
  }

  .overlay {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.7);
    transition: opacity 500ms;
    visibility: hidden;
    opacity: 0;
  }

  .overlay:target {
    visibility: visible;
    opacity: 1;
  }

  .popup {
    margin: 70px auto;
    padding: 20px;
    background: #fff;
    border-radius: 5px;
    width: 60%;
    position: relative;
    transition: all 5s ease-in-out;
  }

  .popup h2 {
    margin-top: 0;
    color: #333;
    font-family: Tahoma, Arial, sans-serif;
  }

  .popup .close {
    position: absolute;
    top: 20px;
    right: 30px;
    transition: all 200ms;
    font-size: 30px;
    font-weight: bold;
    text-decoration: none;
    color: #333;
  }

  .popup .close:hover {
    color: #06D85F;
  }

  .popup .content {
    max-height: 30%;
    overflow: auto;
  }

  @media screen and (max-width: 700px) {
    .box {
      width: 70%;
    }

    .popup {
      width: 70%;
    }
  }
<a class="button" href="#popup1" onclick="Open()">Let me Pop up</a>

</div>
<title>hi</title>
<div id="popup1" class="overlay">
  <div class="popup">
    <h2>Title</h2>
    <a class="close" onclick="Close()" href="javascript://">&times;</a>
    <div class="content">
      Text

    </div>
  </div>

【问题讨论】:

  • 检查你是否点击了弹出窗口之外的其他元素,也一定要停止事件传播
  • @ImmortalDude 它首先与方法 Open() 有关,因为在单击之前它甚至不在 DOM 中,事件传播在 'close()' 中,对吗?
  • 使用事件监听器并将它们绑定到准备好的文档上,尽可能避免点击,我的意思是使用event.stopPropogation来阻止点击在Dom树上冒泡
  • @ImmortalDude 非常感谢,它现在可以工作了,我添加了 event.stopPropagation();在 open() 方法上,现在它工作正常。

标签: javascript html css


【解决方案1】:

尝试以下方法:

let allElems = document.querySelectorAll("body > div:not(#popup1)"); // Special query selector to get everything except .popup and its children

Array.from(allElems).forEach(elem => // Convert to iterable (with Array.from) and loop through all elements selected
  elem.addEventListener('click', function (e) { // Give them all the click event listener.
    alert('You\'re clicking outside the popup !') 
  });
}

问题主要在于您的 if 声明,因为 .contains 有点搞砸了。另一种方法是将两个元素都转换为字符串并以这种方式进行比较,但这种方法更好也更快(稍微),因为我们不需要检查每一次点击是否在框中。

【讨论】:

  • 感谢您的回答,但现在即使您使用此代码在弹出窗口内单击,它也会显示警报。
  • @aliouawalid 立即尝试。
  • @aliouawawalid 您是否将它与event.stopPropogation() 一起使用,就像您在 cmets 中所说的那样?看看它是否有效。使用查询选择器仍然比仅使用当前代码更稳定。
  • 不,我没有,我也试试你的代码,谢谢。
猜你喜欢
  • 2021-11-21
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2012-12-21
  • 2019-11-10
相关资源
最近更新 更多