点击dom节点里面的子元素,如何点击的是某个节点?

布局如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        margin: 0;
        margin: 0;
        height: 100%;
      }

      .container {
        width: 100%;
        height: 500px;
        position: relative;
        background: rgb(244, 235, 235);
      }

      .node {
        width: 400px;
        height: 200px;
        position: absolute;
        top: 150px;
        left: 60px;
        background: rgb(227, 181, 181);
      }

      .row{
        margin: 5px 0;
        background: gray;
        height: 50px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="node">
        <div class="row">11111</div>
        <div class="row">
            <span style="background: red;">2222</span>
            <span style="background: red; margin-left: 30px;">444</span>
        </div>
      </div>
    </div>
  </body>
</html>

在容器container上绑定了点击监听事件,node里面的布局如下,可能层级更多,如何判断,当点击node里面的任何dom元素时,都表示点击的是node节点?

阅读 624
3 个回答

使用 JavaScript 的 Element.closest() 方法来实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        margin: 0;
        height: 100%;
      }

      .container {
        width: 100%;
        height: 500px;
        position: relative;
        background: rgb(244, 235, 235);
      }

      .node {
        width: 400px;
        height: 200px;
        position: absolute;
        top: 150px;
        left: 60px;
        background: rgb(227, 181, 181);
      }

      .row {
        margin: 5px 0;
        background: gray;
        height: 50px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="node">
        <div class="row">11111</div>
        <div class="row">
          <span style="background: red;">2222</span>
          <span style="background: red; margin-left: 30px;">444</span>
        </div>
      </div>
    </div>

    <script>
      document.querySelector('.container').addEventListener('click', function(event) {
        const nodeElement = event.target.closest('.node');
        if (nodeElement) {
          console.log('Clicked inside the node');
        } else {
          console.log('Clicked outside the node');
        }
      });
    </script>
  </body>
</html>

closest可以匹配特定选择器且离当前元素最近的祖先元素

const container = document.querySelector('.container')
container.addEventListener('click', (event) => {
const target = event.target
const nodeElement = target.closest('.node')
  if (nodeElement) {
    console.log('点击了 node 节点或其子元素')
  } else {
    console.log('点击了其他区域')
  }
})

基于dom事件的事件冒泡规则可以实现你想要的功能
新版浏览器(不考虑兼容性)

  <script>
    var nodeEl = document.querySelector('.container .node');
    document.querySelector('.container').addEventListener('click', function (evt) {
      var targetEl = evt.target;
      var isNodeEl = targetEl === nodeEl || nodeEl.contains(targetEl);
      console.log('是否点击在了.node节点上', isNodeEl);
    }, false);
  </script>

考虑兼容性的写法

 <script>
    var nodeEl = document.querySelector('.container .node');
    document.querySelector('.container').addEventListener('click', function (evt) {
      var targetEl = evt.target;
      var isNodeEl = nodeEl === targetEl || elementContains(nodeEl, targetEl);
      console.log('是否点击在了.node节点上', isNodeEl);
    }, false);
    /**
     * 判断两个元素是否是包含关系
     * @param ele 父元素
     * @param childEle 子元素
     * @returns {Boolean}
     */
    function elementContains (ele, childEle) {
      if (ele === childEle) {
        return false;
      }
      if (!ele) {
        return false;
      }
      if (typeof ele.contains === 'function') {
        return ele.contains(childEle);
      } else {
        while (true) {
          if (!childEle) {
            return false;
          }
          if (childEle === ele) {
            return true;
          } else {
            childEle = childEle.parentNode;
          }
        }
        return false;
      }
    }
  </script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏