如何检查另一个DOM元素树中是否有一些DOM元素?

时间:2014-08-07 14:46:46

标签: javascript dom javascript-events specifications

如何检查另一个DOM元素树中的某个DOM元素?

例如,当您点击主页内容而不是菜单时隐藏菜单,您可以:

document.addEventListener(function (e) {
    var node = e.target;
    do {
        if (node.classList.contains('menu-area'))
            return;
        node = node.parentNode;
    } while (node instanceof HTMLElement);
    closeMenu();
});

请注意,点击非菜单区域时隐藏菜单的常用解决方法是菜单上的event.stopPropagation()和非条件document.addEventListener()

我使用node = node.parentNode===运算符迭代循环创建测试代码:

<style>
div {
  margin: 20px;
  padding: 5px;
  border: 1px green dotted;
}
</style>

<div id="lvl1">
  <div id="lvl2">
    <div id="lvl3">
      Click me
    </div>
  </div>
</div>
<div id="result"></div>


<script>
  var lvl1Node = document.getElementById('lvl1');
  document.addEventListener('click', function(e) {
    var node = e.target;
    do {
      if (lvl1Node === node) {
        document.getElementById('result').innerHTML = "Event from: " + e.target.id;
        return;
      }
      node = node.parentNode;
    } while (node instanceof HTMLElement);
  });
</script>

因此,只需点击<div id='lvl1'>更改<div id="result">区域内部即可。这是正确的解决方案(根据标准)吗?

jQuery / Backbone / Underscore / Mojo /等有这个吗?

1 个答案:

答案 0 :(得分:1)

我不会因此而使用instanceof(尤其是因为它在IE8中无法工作,后者遗憾地继续存在)。测试===您要停止的节点,可能是document.bodydocument.documentElement<html>元素):

document.addEventListener("click", function (e) {
    var node = e.target;
    do {
        if (node.classList.contains('menu-area'))
            return;
        node = node.parentNode;
    } while (node !== document.documentElement);
    closeMenu();
});

或者当你的循环有初始化,测试和&#34;增量时,&#34;它与for很匹配:

document.addEventListener("click", function (e) {
    var node;
    for (node = e.target; node !== document.documentElement; node = node.parentNode) {
        if (node.classList.contains('menu-area')) {
            return;
        }
    }
    closeMenu();
});
  

jQuery / Backbone / Underscore / Mojo /等有这个吗?

对于你上面所做的事情,jQuery有两种方式:

  1. jQuery支持event delegation,因此它会为您进行检查。但我不能立即确定这适用于您正在做的事情。

  2. 如果出于某种原因你无法使用它,jQuery的closest可能会有所帮助:

    if (!$(e.target).closest(".menu-area")[0]) {
        closeMenu();
    }
    

    closest针对选择器测试元素,如果它不匹配,则检查其父节点,依此类推。最后的[0]告诉我们jQuery是否发现了什么。在上面,如果没有找到任何内容(开头为!),我们会关闭菜单。