What's the difference between .closest() and .parents('selector')?
Asked Answered
E

3

13

What's the difference between these? Is one more efficient than the other? I'm a little bit confused to why they both exist. Say I have this markup:

<table>
    <tr>
        <td>...</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
    <tr>
        <td>...</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
    <tr>
        <td>..</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
</table>

From the <span> tags I could use either $(this).closest('tr'); or $(this).parents('tr'); to access the parent/closest <tr> tag.

Ecclesiology answered 23/1, 2012 at 17:33 Comment(0)
T
5

parent returns the immediate parents (one for each element in the caller object) or nothing if the parent does not match the selector. closest returns the closest ancestor matching ancestor for each element (which can be the original element). The third similar function, parents, returns all matching ancestors (not including the element itself).

Generally, closest is more resistant to refactoring the HTML code than parent, if you choose the selector sensibly.

Totipalmate answered 23/1, 2012 at 17:36 Comment(0)
S
18

(Note: The question was edited the day after being asked, changing the question from about parent to being about parents [note the plural]. Which kind of makes a difference!)

Re your original question about parent (singular) vs. closest: parent only ever goes one level up. closest starts with the current element (not just the parent) and keeps searching through ancestors until it finds a match (or runs out of ancestors).

Re your updated question about parents (plural) vs. closest: There are two differences:

  1. Whether the current element is considered (it is with closest, it is not with parents).

  2. Whether the search stops with the first match (it does with closest, it doesn't with parents).

From your original question:

From the tags I could use either $(this).closest('tr'); or $(this).parent('tr');

No, actually. $(this).parent('tr'); would return an empty jQuery object, because the parent of the span doesn't match the selector.

From your updated question:

From the tags I could use either $(this).closest('tr'); or $(this).parents('tr');

You could, provided that your tr isn't also within another tr (e.g., a table containing a table). If that's the case, you'll get the same result. But if you have a table within a table, with parents you'll get multiple trs (all of the ancestor tr elements).

Consider this structure:

<div class="wrapper">
  <div class="inner">
    <p>Testing <span>1 2 3</span></p>
  </div>
</div>

If we hook click on the span, this is what we get back from the three relevant methods:

  • $(this).parent('div') - Empty jQuery object, the parent of the span is not a div.
  • $(this).parents('div') - jQuery object with two divs in it, the "inner" and "wrapper" divs (in that order).
  • $(this).closest('div') - jQuery object with one div in it, the "inner" one.

Here's the result if we hook click on the span and use span as the selector:

  • $(this).parent('span') - Empty jQuery object, the parent of the span is not a span.
  • $(this).parents('span') - Empty jQuery object, the span has no ancestor spans.
  • $(this).closest('span') - jQuery object with the span that was clicked.
Sane answered 23/1, 2012 at 17:35 Comment(4)
@user1534664: :-) I don't know. But thanks for flagging it up, as I notice the question had been edited after I answered it, in a way that required a change to the answer. Very significant change in the question between the day it was asked and the next day when it was edited.Sane
This explains exactly how parent/parents/closet works different from the others,thanks!Ferula
@T.J.Crowder It was very clear. And how jquery handles descendants in this case of closest() ? Is it same ?Whippet
@SanKrish: closest doesn't look at descendants at all, just the elements in the set you call it on and their ancestors.Sane
T
5

parent returns the immediate parents (one for each element in the caller object) or nothing if the parent does not match the selector. closest returns the closest ancestor matching ancestor for each element (which can be the original element). The third similar function, parents, returns all matching ancestors (not including the element itself).

Generally, closest is more resistant to refactoring the HTML code than parent, if you choose the selector sensibly.

Totipalmate answered 23/1, 2012 at 17:36 Comment(0)
C
1

.parent() only goes up one level, while closest() includes the current element, and all parents.

Example (selecting from the bottom div, x = matched elements):

             parent()  parent('body')   .closest('div')  .parents('div')
body     
   div                                                       x
      div       x        <nothing>                           x
this-->   div                                x
Choice answered 23/1, 2012 at 17:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.