jQuery - parent() vs closest()

8

假设我有以下的标记:

<div class="parent">
    <div class="child">
        <div class="grand-child">

我希望从 .grand-child 开始获取 .parent。我可以选择以下两种方法之一:

$('.grand-child').parent().parent();
$('.grand-child').closest('.parent');

总的来说,closest() 似乎是一种更好的方法,因为:

  1. 只有一个函数
  2. 它与 .grand-child.parent 之间的其他 div 无关

具体来说,由于上述优点 #2 的优势,如果我要更改我的标记为

<div class="parent">
    <div class="child">
        <div class="nanny">
            <div class="grand-child">

然后我需要添加一个额外的parent(),但是closest()仍然可以正常工作。

那么你为什么会选择parent()或者closest()呢?


1
也许你需要访问元素的父级,而你并不关心(甚至不知道)它是什么。这时你就可以使用.parent()方法。 - Regent
在使用jQuery的parent()closest()函数时,有许多差异和需求。它取决于您实际需要什么。请查看它们之间的区别此处 - Avinash Babu
看起来你的应用程序非常适合使用 closest。但是,如果你只想要上一级,例如,那么 parent 就会非常有用。parent 的优点在于你不需要标签来找到它。这完全取决于你的需求。 - lurker
有很多情况适合使用parent。假设你不知道它是什么类或ID,甚至标签,但你知道你想要实际的父元素?closest()对于特定目标更有效,尤其是当不确定它们离多远时。 - charlietfl
注意closest实际上是检查元素本身。http://jsfiddle.net/tarabyte/A7ngQ/ - Yury Tarabanko
2个回答

9

你应该使用$('.grand-child').closest('.parent');,因为.parent().parent()严重依赖于你的HTML结构,如果将来在其中一个div内添加另一个div,则使用parent().parent()会得到错误的元素。

假设你有以下HTML:

<div class="parent">
    <div class="child">
        <div class="grand-child-container">
             <div class="grand-child">

如果您使用.parent().parent(),它将会给出错误的元素,所以推荐使用closest(),因为它更好。

根据文档:

parent()获取匹配元素集合中每个元素的父级元素,可选地过滤选择器。

closest()对于集合中的每个元素,通过测试元素本身并穿越其在DOM树中的祖先来获取与选择器匹配的第一个元素。

区别:

如果您向下滚动,可以看到jquery官方网站上这两者之间的区别。

还有一些更好的答案可用于解释这两者之间的区别:

parent vs closest

Difference between jQuery parent(), parents() and closest() functions

性能:

就性能而言,closest()优于parent(),您可以查看closest()和parent()之间的基准测试


谢谢提供信息,但这正是我在描述中所说的为什么我想使用closest()而不是parent() - Kousha
因为closest()独立于DOM结构和变化,而且其性能也比parent()更好。 - Ehsan Sajjad
1
这里的parent vs closest语句是不正确的。基准链接到.parents()和.closest()的基准。.parents()与.parent()非常不同。.parent()是单个指令,速度快。.parents()完全做其他事情,并且非常昂贵——获取整个DOM链中的所有父项,而不仅仅是直接父项:http://api.jquery.com/parents/。.parent()比.closest()快得多,而.closest()比.parents()快。 - Chris Moschini
你能展示基准测试作为支持你的陈述吗? - Ehsan Sajjad
@ChrisMoschini 我已经附上了正确的基准测试,但是 closest()parent() 更快。 - Ehsan Sajjad
这也不测试.parent()。看看代码:idn = denna.attr("id"); console.log($('select.filtration').not('#'+idn)); 在.parent()基准测试中没有调用.parent()。无论如何,这并不神秘 - .closest()是一个循环,而.parent()是一个单一的调用。.parent()会更快,无疑。 - Chris Moschini

3
如果你查看代码,.parent() 基本上只是对 DOM 调用 .parentNode 的封装。它非常快速和高效,因为它实质上只是一个对浏览器内置的单个调用。

https://github.com/jquery/jquery/blob/master/src/traversing.js#L133

.closest(selector)确实更加安全,因为它保证了您不会超过所需的父元素,也不会在达到目标父元素之前停止-无论DOM的实际形状如何。但这显然也更加昂贵。看看代码:

https://github.com/jquery/jquery/blob/master/src/traversing.js#L63

这个循环本身就更加昂贵。每次迭代时,它还要进行更多的检查。在非常深的DOM中,如果您例如使用.closest来询问“此标记是否为X的子级?”,它将在没有其他绑定的情况下向上遍历整个DOM树到body标记。如果您有1000个标记,则需要1000个无意义的循环才能找到它。如果您对调用此函数的标记位置错误,也会发生同样的情况。

因此,在您非常确定结构的DOM中,.parent()非常高效。.closest(selector)适用于不太可信的DOM,但是如果您不知道DOM的外观,则有些危险。

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