检查点击的元素是否是父元素的后代,否则删除父元素。

48

我正在尝试使用原生JS编写脚本(无jQuery),如果有人在元素外部单击,则会将该元素从页面中删除。

然而,这个

包含许多嵌套元素,并且我设置的方式是即使单击第一个元素内的元素,它也会消失。

示例标记:

<div id='parent-node'>
  This is the Master Parent node
  <div id ='not-parent-node'>
     Not Parent Node
    <button>Button</button>
    <div id='grandchild-node'>
      Grandbaby Node
    </div>
  </div>
</div> 

所以我希望无论元素嵌套多深,它都能检查是否是 <div id='parent-node'> 元素的后代。因此,如果我在其中单击,它将不会删除父节点及其所有后代。只有当单击父 div 之外时,div 及其后代才应该被动态移除。

目前这就是我的代码,我知道其中存在一些严重的缺陷:

function remove(id) {
    return (elem = document.getElementById(id)).parentNode.removeChild(elem);
}

document.addEventListener("click", function (e) {
    remove('parent-node');
});

你说得对,这个问题已经被问了很多很多次了。现有的解决方案有什么问题吗?(将其从jQuery调整为vanilla JS非常简单) - Evan Davis
5
为什么要从jQuery转向其他库?最好先学习JavaScript的基础知识,然后再使用类似jQuery的库。特别是如果有人像问题中提到的那样想要使用jQuery! - user3589620
2个回答

86

由于event.target是指被点击的元素的引用,你可以检查#parent-node是否为event.target或者它是否包含event.target作为子元素。

这里有一个例子

在下面的代码片段中,一个事件监听器被附加到文档上。如果触发点击事件的元素不是#parent-node的子孙节点,也不是#parent-node本身,则该元素将被删除。

document.addEventListener("click", function(e) {
  var element = document.getElementById('parent-node');

  if (e.target !== element && !element.contains(e.target)) {
    element.parentNode.removeChild(element);
  }
});

document.addEventListener("click", function(e) {
  var element = document.getElementById('parent-node');
  
  if (e.target !== element && !element.contains(e.target)) {
    element.parentNode.removeChild(element);
  }
});
#parent-node {
  background-color: #f00;
}
<div id='parent-node'>
  This is the Master Parent node
  <div id='not-parent-node'>
    Not Parent Node
    <button>Button</button>
    <div id='grandchild-node'>
      Grandbaby Node
    </div>
  </div>
</div>


4
这正是我要找的,谢谢。关键在于“目标(target)”和“包含(contains)”。 - Dear1ofGdBear
3
谢谢!我简直不敢相信我搜索了我的问题,这个答案完全回答了它。我想实现在自制的模态框之外点击/轻触任何地方都会关闭它。它完美地运作。 - iamse7en
1
非常好,非常感谢您的回答! - Andrew Howard

20
你可以使用 Element.matches() 来判断 Event.target 是否拥有 id 为 #parent-node,或者是后代元素 (#parent-node *)。
然后,如果条件为 false,你可以使用 ChildNode.remove() 删除 parent-node 元素。
document.addEventListener('click', event => {
  if (!event.target.matches('#parent-node, #parent-node *')) {
    document.getElementById('parent-node').remove();
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接