How to Get Anything You Want – part 2
read 39 commentsA couple weeks ago I wrote about traversing the DOM with jQuery’s selector expressions to get any elements in the document (see How to Get Anything You Want – part 1). This time around, I’m going to focus on jQuery methods that provide even more ways to get elements. Some of these methods have a nearly identical counterpart among the selector expressions, but for the most part, the two ways of getting elements complement each other.
Once again, I’ve put together a short paragraph and an ordered list scattered with inline elements such as <em>, <code>, and links. This time it’s wrapped in a DIV with an ID of “jqdt2,” which allows me to focus the demonstration to one area of this page.
Each button below the "jqdt2" DIV will toggle a background color on and off for the parts of the DIV described.
This is a paragraph of text with class=”goofy.” It has an external link, some $(code), and a same-page link.
Click a link to toggle the selector’s highlighting
- get the first list item within the element with an id of “jqdt2.”
$('#jqdt2').find('li').eq(0) - get the first 3 list items. “lt” stands for “less than,” and it starts counting at 0, not 1.
$('#jqdt2').find('li').lt(3)$('#jqdt2').find('li').slice(0,3) - get list items 1, 2, 4, and 5 because they’re the siblings of “funny.”
$('#jqdt2').find('li.funny').siblings() - get all list items that contain the string “silly” as long as they are not greater than the third list item. So, even though list item 4 has the word “silly” in it, it won’t be selected because it is greater than the third.
$('#jqdt2').find('li').not(':gt(2)').contains('silly')$('#jqdt2').find('li').not(':gt(2)').filter(':contains(silly)') - first get all list items inside “jqdt2″ and then filter them so that it ultimately only gets the list items that have a class of “goofy.”
$('#jqdt2').find('li').filter('[@class=goofy]')$('#jqdt2').find('li').filter('[class=goofy]')
or, better yet:$('#jqdt2').find('li.goofy') -
With this example you can see that jQuery’s chaining does not have to occur on a single line, but can be extended to multiple lines for better readability. I’ve also exposed the CSS backgroundColor setting that occurs in all of these examples so that you can see how$('#jqdt2') .find('li.funny') .css('backgroundColor','#0ff') .end() .find('p > strong') .css('backgroundColor','#ff0').end()works. Any time you use one of jQuery’s DOM traversing methods, you can back out of it after you have done what you want with it. Here, the first.find()applies CSS to list items with a class of “funny”; the.end()backs us out of that set of jQuery objects and up to the opening$('#jqdt2'); the final.find()method gets a completely separate group of DOM nodes and applies an aqua background color to it. Also, note that I use the DOM property “backgroundColor” rather than the CSS property “background-color.” While either one should work with jQuery, CSS properties that contain a hyphen will break in some builds. Therefore, I recommend “camel-casing” those properties, just to be safe. -
$('li.goofy')
.parents('#jqdt2')
.children('p')
.next()
.find('a')
.parent()
This final example is a ridiculously circuitous traversal sequence that probably isn’t practical in itself, but I wanted to show a couple more of the methods at your disposal. Unlike all the other examples, this one doesn’t start by narrowing the possible DOM elements to those within an element with an id of “jqdt2.” Instead, it starts with all list items with a class of goofy, and then gets any ancestor with an id of “jqdt2″ (since IDs should be unique, there should be only one). Next, it gets all children of “jqdt2″ that are paragraphs and moves on to the next sibling, which in this case is the ordered list (<ol>). Finally, it looks for links within that ordered list and gets the parent of each. So, by the end of all this skipping around the DOM, we should have selected list items 1 and 4.
For a complete list of DOM traversal methods, visit VisualjQuery.com and click on “DOM” and then “Traversing.” In addition to the ones covered in this entry, you’ll find the following:
.is().prev(): just likenext(), but in the opposite direction-
.parents():functions the same asAs of jQuery 1.1,.ancestors().ancestors()is no longer supported. Please use.parents()instead. .add(): allows you to add another group of jQuery objects
















We want more! We want more!
Awesome! Thanks.
Hey, wait… I’m out of a job! Anyone can do DOM scripting now. Damn you. Damn you to hell.
krdr: I’m working on it. ;)
Chris: You are hilarious! Glad you like the entry. And don’t worry — if client-side scripting follows the pattern of desktop publishing, there will always be a need for people who really know what they are doing.
Thanks for the work. I just started looking in to jQuery seriously after using YUI and YUI-ext a little bit. I’m an ASP.NET platform guy, so making the transition to DOM scripting and being unobtrusive in general is a bit of a head-scratcher. However, with resources like this it’s coming along. Now if I can just figure out when to use
$(this)and when to usethismy life will be a lot easier–kind of odd in JS wherefunctioncan be a method, a class, a function, a…. ;-)Oh, and if you’re looking for another great article to write (that I will wholesale borrow from), how about How to write a jQuery extension to add a toggle selection to group. Jack Slocum has made a nice Element.radioClass() method that I’ve kind of hacked in jQuery for toggling the active tool in a toolbar, but how to make that in to a generic plugin? There’s the rub(ber ducky).
Anyway, thanks for saving me approximately 5 hours of my life.
Congratulations for your work. Its realy a good job.
And thanks for shared….. ;-)
kakaroto
Hallo,
realy good. helped me diving into jQuery.
if you can do such a thing for html tables with indirect references, this would be realy cool.
selection all the rows there the cell of the column that corresponds to the column where the header contains ‘Sun’ gets emphasized.
and this also for columns.
Thx, Willi
ei thanks! i will try this code.. actually i need this kind of code for my new project.
im using jquery for a month now and its cool!!
thanks again!
Hi Karl, another great post.
Im a complete newbie to jQuery and have one little issue that I hope you can help me with (dont scoff :p)
I want to add nice jquery effects to some xhtml navigation so the sub menu will fade in. The basic xhtml will be similar to that below:
<div id=”nav”>
<ul>
<li><a href=”#”>dfgdfg</a></li>
<li><a href=”#”>dfgdfg</a>
<ul>
<li><a href=”#”>dfgdfg</a></li>
<li><a href=”#”>dfgdfg</a></li>
</ul>
</li>
<li><a href=”#”>dfgdfg</a></li>
<li><a href=”#”>dfgdfg</a>
<ul>
<li><a href=”#”>dfgdfg</a></li>
<li><a href=”#”>dfgdfg</a></li>
</ul>
</li>
</ul>
</div>
The key is i cant have any class or id on any ul/li as its all cms driven, the surrounding div ID should allow for the code focus.
I got as far as this with the JQuery side of things:
$(document).ready(
function(){
$(“li”).hover(function(){
$(‘li’).children(‘ul’).fadeIn();
},function(){
$(‘li’).children(‘ul’).fadeOut();
});
}
);
But this obviosuly doesnt do the trick. It shows both submenus on any li.
What am I doing wrong?
Hi Adrian,
Instead of
$('li').children('ul'), try$(this).children('ul').Excellent :) Works a dream….
Much appreciated Karl, keep up the good work….
Thanks for a great site, Karl! I’m just getting into jQuery and I couldn’t do it without your tutorials. I think I have the same question as willi above. I’m trying to highlight each column in a table when someone hovers over one of the elements. I’ve added classes to each of the related ths and tds, and I can get it to work but only if I define the class absolutely, like this:
(The highlight is done with the css class “on”.) What I need is for it to change as the mouse moves… I can’t figure out how to create a variable to hold the class of the element being hovered over, which would then be used to select the other elements with the same class, which I think would be something like this:
I guess that’s the heart of my question: How can you select an attribute of the current element being clicked or hovered over?
thanks for the help and keep up the great work!
-frances
Hi Frances,
I think I know what you’re getting at. I think the secret is to make use of the
thiskeyword. Something like this:Awesome! It’s so simple and yet I was tying myself in knots trying to figure it out. I think I still have to get the hang of jQuery’s chaining… Thanks so much for the help and a great example to learn from!
This is great article, thanks, Karl!
I`m newbie in JQuery and ask you to help.
I have this code:
The question: how to get
#left ul li ulwhich have inside<a class="active">.The problem (for me): tag a is on unknown level inside ul
For previous post:
Is this correct?
Hi Andy,
Well, if the class is “active”, then you’ll need to have …
:has(.active), but other than that, it looks fine. You probably don’t need the first ul, unless you have to distinguish it from an ol. So, all together, it might look like this:$('#left li ul:has(.active)')Thanks a ton for the tutorial! I was able to solve a problem with a selector that was below the hovered item like:
This worked incredibly easily to show a div when you hovered. Basically, it shows an edit link when you hover, and hides it when you lose hover.
Thanks again for a great site!
Oops … errant comma. Fix below:
Please don’t tell my friends I’m an idiot:
Please don’t tell my friends I’m an idiot
If they are true friends they will already know :)
hi karl,
i’m trying to use the following code and what i want is to hide a div “.nextblock” when i click any where on the page, except on that div. But this is not working. It hides the block even if i click on the block.
$(“body,.div”).not(“.nextBlock”).click(function () {
$(“.nextBlock”).hide();
});
This one works when i use a image instead of a div or a table in the filter.
$(“body,.img”).not(“.testImg”).click(function () {
$(“.nextBlock”).hide();
}); // this works
can you please tell me why the first one is not working and a better way to implement it.
Thanks!
Hi,
thanks for the work – but in my opinion the way it is presented lacks any senseful
structure.
Which included js- and css-files are needed for the examples, which are for the rest of the page?
Everything is so mangled into anything else – i tried to get my hands on the relevant parts just dealing with the examples – sysiphos like work – so i dropped it.
I don’t think the examples are of any help when presented like this.
Sorry, one more,
it is even no longer obvious which of the included js-files is the original jquery-js-file.
Why call it “somehow” if it has a name: “jquery”?
Has it been altered to achieve the results of the examples?
Do i need ‘a’ or maybe rather ‘a.js’ to reproduce the examples?
Helplessly stuck
Up to now
i found out that the really needed files for the examples to work are:
- syntax_hilite_css.css
- sytax_hilite_js.js
- dom-traverse1.js
- a.css
- a.js
It seems that a.js is an excerpt of the jquery.js, or maybe the jquery.js is not used at all here
and a.js is, well, what is it?
Which file does what?
Why do you give beginners such a hard time getting a grip on how it works “as a whole”?
I got the point.
This is not meant to be a working (standalone) example for highlighting specific parts of a web page – it is examples for how to reach/select elements.
So my comments are not too much on topic, sorry for that.
Still i think separating example code (and the included files needed just for the examples) from the rest of the page is a good idea.
Hi Frank,
Thanks for the feedback. I can see how it could have been confusing for you if you were looking for a packaged solution to a particular problem. You’re right in your last comment, though, that this post is more of an exercise rather than a standalone example. Think of it more as training drills than as a game. Still, I appreciate where you’re coming from and will consider how to make this sort of thing clearer in future posts. Thanks.
is it possible to get the id’s of all the children of an element and throw it into an array, or use it in a loop?
I am dynamically adding ‘a’ tags with unique id’s inside a div, and for each a tag I want to init a plugin like lightbox. I hope this makes sense…
Sure, you could do something like this:
Or, you could use the
.map()method:Karl,
I see you have been such a big help to everyone here! Thank you for that!
I have a small issue I’m trying to figure out. I apologize for the length of this comment in advance.
I want to add a class to the first 3 ‘p’ in my divs on a page. And there are never the same amount of “p”s in the divs.
The HTML looks something like this.
<div class=”myclass”>
<p></p>
<p></p>
</div>
<div class=”myclass”>
<p></p>
<p></p>
<p></p>
</div>
<div class=”myclass”>
<p></p>
<p></p>
<p></p>
<p></p>
</div>…
jquery I have so far is…
$('.naetext').children('p:lt(3)').addClass('newclass');What this does is it adds a class of “newclass” to the first 3 “p”s consecutively and not the first 3 of each “set” of “p”s
So my HTML looks like this
<div class=”myclass”>
<p class=”newclass”></p> added class 1
<p class=”newclass”></p> added class 2
</div>
<div class=”myclass”>
<p class=”newclass”></p> added class 3
<p></p>
<p></p>
</div>
<div class=”myclass”>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
What I need is this…
<div class=”myclass”>
<p class=”newclass”></p> added class 1
<p class=”newclass”></p> added class 2
</div>
<div class=”myclass”>
<p class=”newclass”></p> added class 1
<p class=”newclass”></p> added class 2
<p class=”newclass”></p> added class 3
</div>
<div class=”myclass”>
<p class=”newclass”></p> added class 1
<p class=”newclass”></p> added class 2
<p class=”newclass”></p> added class 3
<p></p>
</div>
Man, I hope that makes sense. I appreciate your time!
I’m sorry, my jquery actually is this:
$('.myclass').children('p:lt(3)').addClass('newclass');No problem, Erik. Try this:
Fantastic, thanks Karl!
I didn’t realize their is an “each” function. That is so cool.
It worked.
hi how can we check for td with 2 classes with different class name in single tr ,thanks
$('#table1 tr .abc )$('#table1 td.class-one.class-two')hi,
how can i make the selectors case sensitive?
is there any smart way?
example: remove all SPAN elements with the same background-color
_ lower_
_upper_
_both_
$("span[style*='color']").remove();$("span[style*='aaccee']").remove();thanks for all the tipps and tutorials,
nelson
sorry, P elements not SPAN :)
lower
upper
both
lower
upper
both
{p style=”background-color: #aaccee”}lower{/p}
{p style=”BACKGROUND-COLOR: #AACCEE”}upper]{/p}
{p style=”Background-Color: #aaccee”}both{/p}
Finally I learned how end() works!!!, thanks so much.