如何在jQuery中获取元素的第n级父元素?

159
当我想获取元素的第三级父级时,我必须编写 $('#element').parent().parent().parent()。 是否有更优化的方法?

2
我想通过数字(级别)获取元素,因为我的元素可能没有任何类ID或名称。 - Artur Keyan
1
如果您计划重复使用此功能,则最佳解决方案是制作一个jQuery插件。 - zzzzBov
3
请参考http://jsperf.com/jquery-get-3rd-level-parent 进行性能比较。 - a'r
1
另一个好用的工具是“.closest()”函数。$('li.item').closest('div')将会给你最接近li.item祖先的DIV。当你不知道元素在上面多少级,但你知道它的标签名/类名/其他某些属性时,这个函数非常有用。 - Graham
13个回答

284

由于parents()返回的是从最近祖先元素到外层元素排序的,因此您可以将其链接到eq()中:

$('#element').parents().eq(0);  // "Father".
$('#element').parents().eq(2);  // "Great-grandfather".

我可以使用$('#element').parents()[2]吗?还是必须使用eq(2)? - Artur Keyan
1
这种方法无法用于多个元素的选择,更安全的方式是:$('.element').first().parents().eq(num); - zzzzBov
8
@Arthur,使用[2]将返回底层DOM元素,而使用eq(2)将返回一个jQuery对象。 - Frédéric Hamidi
1
@zzzzBov,非常正确,但在提问者的情况下只会选择一个元素(因为他匹配了一个id)。 - Frédéric Hamidi
@Henry,是的,但我意识到提问者在阅读您的评论之前正在匹配ID,老实说 :) - Frédéric Hamidi
显示剩余8条评论

29

根据你的需求而定,如果你知道你要查找的父元素,可以使用.parents()选择器。

例如: http://jsfiddle.net/HenryGarle/Kyp5g/2/

<div id="One">
    <div id="Two">
        <div id="Three">
            <div id="Four">

            </div>
        </div>
    </div>
</div>


var top = $("#Four").parents("#One");

alert($(top).html());

使用索引的示例:

//First parent - 2 levels up from #Four
// I.e Selects div#One
var topTwo = $("#Four").parents().eq(2);

alert($(topTwo ).html());

我知道这种方法,但我想提高水平。 - Artur Keyan
3
请往下阅读答案,一切将会揭晓!(我已给出了例子级别) - Henry
这对于所有其他类型的选择器都很有效。例如,如果您想要具有特定类的所有父级和祖先的列表,这将返回它们。 - darksky

9
你可以给目标父元素一个id或class(如myParent),然后使用$('#element').parents(".myParent")来引用它。该方法可以在IT技术中使用。请注意,不要删除HTML标签。

我想只输入数字并获取元素,因为我的元素可能没有任何类ID或名称。 - Artur Keyan

7

使用closest()未找到任何答案,当您不知道所需元素向上多少级时,我认为这是最简单的答案,因此发布一个答案:
您可以使用closest()函数与选择器结合使用,从元素向上遍历时获取第一个匹配的元素:

('#element').closest('div')    // returns the innermost 'div' in its parents
('#element').closest('.container')    // returns innermost element with 'container' class among parents
('#element').closest('#foo')    // returns the closest parent with id 'foo'

6
更快的方法是直接使用JavaScript,例如:
var parent = $(innerdiv.get(0).parentNode.parentNode.parentNode);

这在我的浏览器上比链接jQuery .parent()调用要快得多。
请参见:http://jsperf.com/jquery-get-3rd-level-parent

通过“显著更快”我们指的是在速度方面有一个数量级的差异(在Chrome 51上运行jQuery 1.10.1)。如果您正在调整速度,那么肯定值得实施。 - Iain Fraser

3
很简单,只需使用


$(selector).parents().eq(0); 

其中0为父级别(0代表父级,1代表父级的父级等等)


3
只需添加:eq()选择器,如下所示:
$("#element").parents(":eq(2)")

您只需指定父级的索引:0表示直接父级,1表示祖父级,...


这是完成工作的最快方法。 以下是证明它的基准测试:https://jsperf.com/jquery-get-element-s-nth-parent - bekliev

3
如果您计划重复使用此功能,则最佳解决方案是创建一个jQuery插件:
(function($){
$.fn.nthParent = function(n){
  var $p = $(this);
  while ( n-- >= 0 )
  {
    $p = $p.parent();
  }
  return $p;
};
}(jQuery));

当然,您可能希望扩展它以允许可选选择器等其他内容。
需要注意的是:此方法使用0索引作为父元素,因此nthParent(0)与调用parent()相同。如果您更喜欢使用1个索引,请使用n-->0。

我认为你会发现这部分更快:var p = 1 + n; while (p--) { $p = $p.parent(); } 如果你想改成基于1的,由于Javascript是“falsey”,你可以使用:while (n--) { $p = $p.parent();} 从而避免了条件检查。 - Mark Schultheiss
@Mark Schultheiss,这不仅仅是关于速度的问题,可靠性也很重要。如果有人无知地调用nthParent(-2),你的函数会发生什么?你的例子是错误的。 - zzzzBov
(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery)); - Mark Schultheiss
@Mark Schultheiss,再次强调可靠性。我的函数为选择中的每个元素返回第n个父级,而你的函数返回parents列表中的第n个元素,这对于包含多个元素的选择是不正确的。 - zzzzBov
关于-2的返回值,以及在您的示例中使用var p = n >? (1 + n):1;而不是“nothing”的情况下,将返回第一个父级 - 或者在我的示例中它打破循环的地方。因此,它可能应该是:(function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); 如果您不想返回任何内容。 - Mark Schultheiss
我考虑检查负数并选择子代,使用 0 进行自我引用,此时 nthParent 将是一个不准确的名称。 - zzzzBov

3
如果您有一个常见的父级div,可以使用parentsUntil()方法。链接 例如: $('#element').parentsUntil('.commonClass') 优点是您无需记住该元素与通用父元素(commonclass定义)之间有多少代。

1

你也可以使用:

$(this).ancestors().eq(n) 

例如:$(this).ancestors().eq(2) -> this 的父级的父级。


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