查找两个元素的第一个共享父元素

时间:2010-11-04 17:57:47

标签: javascript jquery

假设我有这个DOM结构

<body>
    <p>
        Hello
        <i>how <b>are</b> you</i>
        and
        <i>what <b>are <tt>you</tt> going</b> to</i>
        eat tonight?
    </p>
</body>

使用jQuery我想了解

的FIRST共享父级
<b>are</b>

<tt>you</tt>

从下到上,这将是&lt; p>不是&lt;身体&gt;标签

关于如何使用jQuery确定第一个共享父级的任何想法?

6 个答案:

答案 0 :(得分:9)

像这样:

$(a).parents().filter(function() { return jQuery.contains(this, b); }).first();

如果b是选择器(而不是DOM元素),您可以将其更改为:

$(a).closest(':has(b)');

这个更短,但速度要慢得多。

ab的顺序无关紧要;如果b离父母更近,它会更快。

答案 1 :(得分:5)

您可以将.parents().filter()结合使用,如下所示:

$("b:first").parents().filter($("tt").parents()).first()
//or more generic:
$(elem1).parents().filter($(elem2).parents()).first()

这会得到所有共享父母,然后您可以使用.first().last() ......无论需要什么。

You can test it here。请注意,这比.has()要快得多,因为我们只是比较2个DOM元素集,而不是递归地比较多个元素集。此外,结果集将按照文档的顺序排列,在此示例中为<p>,然后是<body>

答案 2 :(得分:1)

使用jQuery closest()方法

$("b:contains('are')").closest(":has(tt:contains('you'))")

这是demo http://www.jsfiddle.net/65hSW/

答案 3 :(得分:0)

非jQuery版本:

var arrayContains = Array.prototype.indexOf ?
    function(arr, val) {
        return arr.indexOf(val) > -1;
    }:

    function(arr, val) {
        var i = arr.length;
        while (i--) {
            if (arr[i] === val) {
                return true;
            }
        }
        return false;
    };


function getCommonAncestor(node1, node2) {
    var ancestors = [], n;
    for (n = node1; n; n = n.parentNode) {
        ancestors.push(n);
    }

    for (n = node2; n; n = n.parentNode) {
        if (arrayContains(ancestors, n)) {
            return n;
        }
    }

    return null;
}

答案 4 :(得分:0)

这是一个非常简单的非jquery解决方案:

function sharedParent (elem1, elem2) {
for (; elem1!= null; elem1=elem1.parentNode) {
  for (var e2=elem2; e2!= null; e2=e2.parentNode)
    if (elem1 == e2) return elem1;
  }
return null;
}

答案 5 :(得分:0)

jQuery( function(){

  var elem1 = jQuery("#a");
  var elem2 = jQuery("#b");

  var foo1 = elem1.parents().has(elem2).first().attr("tagName");
  var foo2 = elem1.closest(":has(" + elem2.selector + ")").first().attr("tagName");

  alert( foo1 );
  alert( foo2 );


});

JSBIN