【问题标题】:Check if an element is a child of a parent检查元素是否是父元素的子元素
【发布时间】:2011-04-14 19:05:41
【问题描述】:

我有以下代码。

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>

<div id="hello">Hello <div>Child-Of-Hello</div></div>
<br />
<div id="goodbye">Goodbye <div>Child-Of-Goodbye</div></div>

<script type="text/javascript">
<!--
function fun(evt) {
    var target = $(evt.target);    
    if ($('div#hello').parents(target).length) {
        alert('Your clicked element is having div#hello as parent');
    }
}
$(document).bind('click', fun);
-->
</script>

</html>

我希望只有当Child-Of-Hello 被点击时,$('div#hello').parents(target).length 才会返回 >0。

但是,只要我点击任何地方,它就会发生。

我的代码有问题吗?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    如果您只对直接父代感兴趣,而不对其他祖先感兴趣,则可以使用parent(),并为其指定选择器,如target.parent('div#hello')。

    示例: http://jsfiddle.net/6BX9n/

    function fun(evt) {
        var target = $(evt.target);    
        if (target.parent('div#hello').length) {
            alert('Your clicked element is having div#hello as parent');
        }
    }
    

    或者如果你想检查是否有任何祖先匹配,那么使用.parents()。

    示例: http://jsfiddle.net/6BX9n/1/

    function fun(evt) {
        var target = $(evt.target);    
        if (target.parents('div#hello').length) {
            alert('Your clicked element is having div#hello as parent');
        }
    }
    

    【讨论】:

    • 没有jquery怎么办?
    【解决方案2】:

    您只需交换两个术语即可让您的代码工作:

    if ($(target).parents('div#hello').length) {
    

    你让孩子和父母走错了路。

    【讨论】:

    • var target = $(evt.target); 所以你的代码应该是if (target.parents('div#hello').length) { 而不是...$(target)...
    【解决方案3】:

    .has() 似乎是为此目的而设计的。由于它返回一个 jQuery 对象,因此您还必须测试 .length:

    if ($('div#hello').has(target).length) {
       alert('Target is a child of #hello');
    }
    

    【讨论】:

    • @redanimalwar 对;这就是它的作用。找到父元素,然后检查 target 是否在其中。
    【解决方案4】:

    如果你有一个没有特定选择器的元素,但你仍然想检查它是否是另一个元素的后代,你可以使用jQuery.contains()

    jQuery.contains(容器,包含)
    描述:检查一个 DOM 元素是否是另一个 DOM 元素的后代。

    您可以将父元素和要检查的元素传递给该函数,如果后者是第一个元素的后代,则返回。

    【讨论】:

    • 特别注意$.contains带DOM元素和不是 jQuery实例,否则它总是返回false。
    • 另一个要记住的细节:$.contains 如果两个参数是同一个元素,则永远不会返回 true。如果需要,请使用domElement.contains(domElement)。
    【解决方案5】:

    最终改用 .closest()。

    $(document).on("click", function (event) {
        if($(event.target).closest(".CustomControllerMainDiv").length == 1)
        alert('element is a child of the custom controller')
    });
    

    【讨论】:

    • 在现代浏览器上,这也可以在没有 jquery 的情况下工作:if (event.target.closest('selector'))。
    【解决方案6】:

    除了其他答案,你还可以像这样使用这种鲜为人知的方法来抓取某个父级的元素,

    $('child', 'parent');
    

    在你的情况下,那将是

    if ($(event.target, 'div#hello')[0]) console.log(`${event.target.tagName} is an offspring of div#hello`);
    

    注意子级和父级之间使用逗号及其单独的引号。如果它们被相同的引号包围

    $('child, parent');
    

    您将拥有一个包含这两个对象的对象,无论它们是否存在于它们的文档树中。

    【讨论】:

    • 这是一个很酷的 hack,但不适用于没有 id 或类的元素
    【解决方案7】:

    适用于 IE8+ 的 Vanilla 1-liner:

    parent !== child && parent.contains(child);
    

    在这里,它是如何工作的:

    function contains(parent, child) {
      return parent !== child && parent.contains(child);
    }
    
    var parentEl = document.querySelector('#parent'),
        childEl = document.querySelector('#child')
        
    if (contains(parentEl, childEl)) {
      document.querySelector('#result').innerText = 'I confirm, that child is within parent el';
    }
    
    if (!contains(childEl, parentEl)) {
      document.querySelector('#result').innerText += ' and parent is not within child';
    }
    <div id="parent">
      <div>
        <table>
          <tr>
            <td><span id="child"></span></td>
          </tr>
        </table>
      </div>
    </div>
    <div id="result"></div>

    【讨论】:

    • 谢谢,太棒了!递归很酷。我想知道函数的参数如何成为(内部)函数操作的对象。能否提供更多相关信息的链接?
    【解决方案8】:

    要了解Aleksandr Makov's answer 的更多背景信息,查看以下页面可能会有所帮助。

    https://developer.mozilla.org/en-US/docs/Web/API/Node/contains

    Node.contains()
    Node 接口的 contains() 方法返回一个布尔值,指示节点是否是给定节点的后代,即节点本身、其直接子节点之一(childNodes)、子节点的直接子节点之一,等等.

    这意味着,答案不是使用隐蔽函数。

    【讨论】:

      【解决方案9】:

      没有 jquery

      target.matches() 和 :scope

      如果您想查看目标元素是否有与某些选择器匹配的父元素,请使用目标上的.matches() method 并传递选择器,后跟:scope pseudo class。

      这里的:scope 指的是目标元素,因此您可以使用:where pseudo class 中的@ 来帮助您编写一个干净的选择器。

      在下面的示例中,我们将匹配作为a、button 或summary 元素的后代的所有目标元素。

      const app = document.getElementById("app");
      
      app.addEventListener("click", (event) => {
        if (
          event.target.matches(
            ":where(a, button, summary) :scope"
          )
        ) {
          console.log("click", event.target.parentNode.tagName);
        }
      });
      <div id="app">
        <button>
          <span>Click Me</span>
        </button>
      
        <a href="#">
          <span>Click Me</span>
        </a>
        
        <details>
          <summary>
            <span>Click Me</span>
          </summary>
        </details>
        
        <span>Click Me</span>
      <div>

      注意选择器:where(a, button, summary) :scope也可以写成:

      a :scope,
      button :scope,
      summary :scope
      

      parent.contains()

      如果您有兴趣查看目标元素是否是特定元素的子元素,请在潜在父元素上使用 .contains():

      const app = document.getElementById("app");
      const button = document.getElementById("button");
      
      app.addEventListener("click", (event) => {
        if (button.contains(event.target)) {
          console.log("click");
        }
      });
      <div id="app">
        <button id="button">
          <span>Click Me</span>
        </button>
        
        <span>Click Me</span>
      <div>

      【讨论】:

        猜你喜欢
        • 2022-12-16
        • 1970-01-01
        • 2020-02-21
        • 2019-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-27
        • 2014-11-15
        相关资源
        最近更新 更多