假设我有这个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确定第一个共享父级的任何想法?
答案 0 :(得分:9)
像这样:
$(a).parents().filter(function() { return jQuery.contains(this, b); }).first();
如果b
是选择器(而不是DOM元素),您可以将其更改为:
$(a).closest(':has(b)');
这个更短,但速度要慢得多。
a
和b
的顺序无关紧要;如果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'))")
答案 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 );
});