$($(this).parent().parent().parent().parent().parent().parent().children()[0]).html()
5 Answers
.parent().parent().parent().parent().parent().parent()
This can be much simplified by using parents()
which returns an array, which you can just access with an index. I.e. you can replace the above with:
.parents()[5]
The upsides of this, besides being more concise, are that it the reader of your code can see which parent you're accessing without having to count the calls to parent
and that if you ever need to access a different parent, you can just change the number instead of having to add or remove calls to parent
.
-
\$\begingroup\$ For the record, the slightly more ‘jQuery’ way to do this would be
.parents().get(5)
. But obviously sepp2k’s suggestion is more efficient (no overhead because of an extra function call) and shorter. \$\endgroup\$ Commented Mar 25, 2011 at 12:51 -
\$\begingroup\$ You can also do stuff like this.
.parents('form :first');
first being immediate parent to last being outermost container. \$\endgroup\$ Commented Aug 8, 2012 at 23:19
This...is pretty bad. But there's no real way to tell how bad it has to be given other constraints. For instance, if this is a JS file meant to affect a page whose HTML you don't have control over, then you can't do much better than something like
$(this).parents(":eq(5)").children(":eq(0)").html()
If this is an element you have to access a lot, consider adding an id or class to it, then selecting by that.
$("#fifth-parent-first-child").html() //or something descriptive
Again, if you don't have access to the HTML, you'll need to add it yourself at runtime
$(document).ready(
function () {
$(foo).parents(":eq(5)").children(":eq(0)").addClass("something-descriptive")
}
);
$(".something-descriptive").html()
Consider pasting some surrounding code for more insight.
-
1\$\begingroup\$ Applying a tag in the HTML is the best approach, and applying a tag dynamically is next. Specifying the number of parent elements as a number is fragile--your code will break if the page's structure is modified. \$\endgroup\$ Commented Mar 14, 2011 at 13:24
-
\$\begingroup\$ Using
:eq(5)
as a selector is significantly more expensive then calling.eq(5)
if your not doing complex composition always use the cheaper methods instead. \$\endgroup\$– RaynosCommented Mar 26, 2011 at 17:42 -
\$\begingroup\$ @JoshEarl - I very much agree, I have had a lot of mysteries and headaches dealing with other's jQuery code which relies on the page structure. \$\endgroup\$ Commented Apr 1, 2011 at 15:34
Besides what sepp2k said:
Instead of accessing the DOM object of the first child and then rewrapping it in a jQuery object, you can use the method .eq()
to access it directly.
So instead of this:
$($(this)/* ... */.children()[0]).html()
Use this:
$(this)/* ... */.children().eq(0).html()
And there are possibly more ways to optimize it, if you show the HTML it's operating on.
-
\$\begingroup\$ Thanks, that was one of the things I was looking for, very helpful :) \$\endgroup\$ Commented Mar 12, 2011 at 19:27
-
\$\begingroup\$ Can you combine your answers into
$($(this).parents().eq(5).children().eq(0)).html()
? \$\endgroup\$ Commented Mar 12, 2011 at 22:11 -
\$\begingroup\$ Not quite.
$(this).parents().eq(5).children().eq(0).html()
See also Inaimathi's answer. \$\endgroup\$– RoToRaCommented Mar 13, 2011 at 11:34
1. Instead of doing so many .parent()
calls, you can use .parents()
:
$(this).parents(':eq(5)');
2. You can use .eq()
to get the nth occurrence of an element, you don't need to do [0]
and pass it to jQuery again.
$($(this).parents(':eq(5)').children()[0]).html()
This is better:
$(this).parents(':eq(5)').children().eq(0).html();
Though jQuery has a :first-child
selector, which is more understandable:
$(this).parents(':eq(5)').find(':first-child').html();
Reference
Assuming you don't have access to the html (where you could assign an id the child), the only real option you have is:
$(this).parents().eq(5).children().eq(0).html();
if you are going to be accessing the element more than once you could assign it on load:
$(document).ready(function(){
window.foo = $(bar).parents().eq(5).children().eq(0);
});
...
foo.html();
knowing more about why you need to do dom traversing, may yield further advice.
Is it actual code from a project rather than pseudo-code or example code?
in our Help Center for more details. Also could use a bit more context. \$\endgroup\$