views:

104

answers:

3

What is the better way to get a parent node for the following example of code?

...
<tr>
  <td>
    <table>
      <tr>
        <td>
          <div class="block_data">
            Hello world!!
          </div>
        </td>
      </tr>
    </table>
  </td>
</tr>




/*Javascript code 1*/
$('.block_data').parents('tr').first()...


/*Javascript code 2*/
$('.block_data').parent().parent()...

Which of the two codes is faster (considering perfomance, not coding)? Imagine a situation like that, with a lot of parents:

...
<tr>
  <td>
    ...
  </td>
</tr>
...
<tr>
  <td>
    <div>
      <div>
        <div>
          <div class="block_data">
            Hello world!!
          </div>
        </div>
      </div>
    </div>
  </td>
</tr>
A: 

In my opinion it is better to use parents() because in case your code changed you would refer to completely other element. It is bit slower thought, but you've got just few nodes there so it should't be much of the impact.

It is better to use parents() and find the element you need than (in some other case) to write many .parent().parent().parent().parent().parent().parent().parent().parent(). Code is more maintainable that way, imho.

rochal
+5  A: 

Since neither one of them actually work correctly for your desired functionality, the question of which method is faster is sort of beside the point, don't you think? You are looking for closest(), not parent() or parents(). In general, it's probably a bad idea to think about performance until you are positive you have a method which works correctly.

Craig Stuntz
OP's use of `.parents()` in the example provided *does* work correctly for the desired functionality, because it is followed by `.first()`. As such, it emulates the functionality of `.closest()`. Although, I'd use `.parents('tr:first')` in that case.
patrick dw
He followed it with `fisrt()`, not `first()`.
Craig Stuntz
Craig - You don't *really* believe that that wasn't a typo, do you? :o) I would have a tough time believing that OP thought there actually was a `.fisrt()` method in jQuery.
patrick dw
You don't *really* believe that I *don't* think it was a typo, do you? But that doesn't change what I wrote: If you show me two pieces of bad code and ask me which is faster, you're asking the wrong question.
Craig Stuntz
Craig - Sometimes a person just needs to look beyond the typos and understand the point of the question. Your suggestion to use `.closest()` is a good one, but the answer is a little misleading since the *intended* code is a proper solution. Don't take it personally when someone corrects your answer. It's not like I down-voted you. My assumption was that you didn't notice the `.first()` call at first. But then your comment that pointed out the typo does make it sound like you thought OP actually meant `.fisrt()`.
patrick dw
...somewhere in this exchange I expect a *"My Dad could beat up your Dad"* reply...
Chad
@Chad - I certainly hope it doesn't degrade into that. :o) One great thing about SO is the ability to comment on and improve each other's answers. I didn't mean for my original comment (or any of my comments) to be an offense.
patrick dw
@patrick dw, it was just a funny back and forth! Had to comment
Chad
@patrick, I didn't take it personally, and I was never offended. I just think "be careful to keep away from premature optimization" is *at least* as valuable an answer as "here's the right jQuery API call to use" -- likely moreso. I believe I understand the point of the question, but I'm convinced that it was the wrong question.
Craig Stuntz
Craig - Alright. I see your point. :o)
patrick dw
+1  A: 

Your use of

.parents('tr').first()

will withstand changes to the DOM where the element with the handler becomes more deeply nested.

In that case, I'd prefer to use

.parents('tr:first')

Another answer mentioned closest('tr'). It is really a tossup between the two.

Some like using .parents() because its name is more descriptive of what it is doing. But you need to be aware that it will return more than one result if there are multiple matches. That's where you need .first() or :first to get just the first one.

Between .closest() and .parents(), performance varies based on browser. I found in some quick tests that IE likes .parents() better, while FF and Webkit like .closest() better.

patrick dw