解决方案1

其中之一是实现一个普通的 JavaScript 解决方案。

HTML 中的弹出窗口将如下所示:

<!DOCTYPE html>
<html>
  <head>
    <title>文档的标题</title>
  </head>
  <body>
    <div class="flyout" id="flyout-example">
      <h5 class="flyout-title">This could be a flyout;</h5>
      <div class="flyout-debug" id="flyout-debug"></div>
      <div class="flyout-buttons">
        <button class="button button-outline" type="button">Cancel</button>
        <button class="button" type="button">Ok</button>
      </div>
    </div>
  </body>
</html>

因此,为了检测元素外的点击,最好为整个文档元素添加一个侦听器。
因此,主循环将从单击的目标元素向上移动 DOM,以搜索该元素的祖先是否属于弹出式容器。

花哨的 ES6 功能提供了以下 JavaScript 代码供使用:

<!DOCTYPE html>
<html>
  <head>
    <title>文档的标题</title>
  </head>
  <body>
    <div class="flyout" id="flyout-example">
      <h5 class="flyout-title">This could be a flyout;</h5>
      <div class="flyout-debug" id="flyout-debug"></div>
      <div class="flyout-buttons">
        <button class="button button-outline" type="button">Cancel</button>
        <button class="button" type="button">Ok</button>
      </div>
    </div>
    <script>
      document.addEventListener("click", (evt) => {
        const flyoutEl = document.getElementById("flyout-example");
        let targetEl = evt.target; //被点击的元素  
        do {
          if(targetEl == flyoutEl) {
            //This is a click inside, does nothing, just return.
            document.getElementById("flyout-debug").textContent = "Clicked inside!";
            return;
          }
          //Go up the DOM
          targetEl = targetEl.parentNode;
        } while (targetEl);
        //This is a click outside.      
        document.getElementById("flyout-debug").textContent = "Clicked outside!";
      });
    </script>
  </body>
</html>

请注意,此代码可以在现代浏览器上运行。
对于较旧的浏览器,我们需要调整代码,如下所示:

<!DOCTYPE html>
<html>
  <head>
    <title>文档的标题</title>
  </head>
  <body>
    <div class="flyout" id="flyout-example">
      <h5 class="flyout-title">This could be a flyout;</h5>
      <div class="flyout-debug" id="flyout-debug"></div>
      <div class="flyout-buttons">
        <button class="button button-outline" type="button">Cancel</button>
        <button class="button" type="button">Ok</button>
      </div>
    </div>
    <script>
      document.addEventListener("click", function(evt) {
        let flyoutEl = document.getElementById('flyout-example'),
          targetEl = evt.target; //clicked element      
        do {
          if(targetEl == flyoutEl) {
            //This is a click inside, does nothing, just return.
            document.getElementById("flyout-debug").textContent = "Clicked inside!";
            return;
          }
          //Go up the DOM
          targetEl = targetEl.parentNode;
        } while (targetEl);
        //This is a click outside.
        document.getElementById("flyout-debug").textContent = "Clicked outside!";
      });
    </script>
  </body>
</html>

解决方案2

还有另一种解决方案。
为此,我们需要将单击事件添加到关闭窗口的文档正文。
将一个独立的单击事件添加到容器中,以停止传播到文档正文。

下面是一个例子:

$(window).click(function () { //Hide the menus if visible }); 
$('#menucontainer').click(function (event) {event.stopPropagation();});
JS如何检测元素外的点击事件

JavaScript 中最常用的模式之一是检测元素外的点击。

当用户在该元素外单击时,我们可以应用它来关闭非模态用户界面组件,如菜单或者下拉列表。

这个问题有多种解决方案。

JavaScript DOM 及其元素的描述

文档对象模型 (DOM) 表示一种描述 HTML 和 XML 文档的编程接口的方式。

DOM 有助于使用 Document 对象命令来操作标签和类。
有了它,我们可以将编程语言连接到页面。

DOM 文档是网页的重要组成部分,是所有其他对象的所有者。

因此,要访问网页上的任何对象,我们需要从文档开始。

在 JavaScript DOM 中,我们可以查找和/或者更改元素。

有多种获取元素的方法:通过 ID、通过类名、通过标签名等等。
DOM 数据结构中的几乎所有内容都是可变的。

DOM 的结构看起来像一棵树:元素按照文档结构分层组织。
表示元素的对象具有以下属性:可能用于遍历树的 parentNode 和 childNode。

日期:2020-06-02 22:16:16 来源:oir作者:oir