How to Get Anything You Want – part 1

read 59 comments

With jQuery, you can get to just about anything on a web page. In this entry, I’ll show you a few ways you can use jQuery’s versatile selector expressions to traverse to an element — or group of elements — in the DOM.

I’ve put together a short paragraph and an ordered list scattered with inline elements such as <em>, <code>, and links. It’s all wrapped in a DIV with an ID of “jqdt,” which allows me to focus the demonstration to one area of this page.

Each button below the “jqdt” DIV will toggle a yellow background 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.

  1. list item 1 with dummy link to silly.pdf
  2. list item 2 with class=”goofy
  3. list item 3 SURPRISE!
  4. list item 4 with silly link to silly.pdf
  • $('li:eq(0)') gets the first list item
  • $('li:even') gets all odd-numbered list items (because, in javascript, numbering starts with 0, not 1).
  • $('li:lt(3)') gets the first 3 list items. “lt” stands for “less than,” and it starts counting at 0, not 1.
  • $('li:not(.goofy)') gets list items 1, 3, and 4, because they’re not “goofy.”
  • $('p a[href*="#"]') gets any links that are inside a paragraph and have an “href” attribute starting with “#” — containing “#” anywhere. in other words, same-page links. There are problems with trying to identify same-page links this way. I’ll write about this in an upcoming entry. Note the space between the “p” and the “a”; that means that the “a” is a descendant of the “p.”
  • $('code, li.goofy') gets all code elements and any list item with a class of “goofy.”
  • $('ol .goofy > strong') gets all strong elements that are children of any element with a class of “goofy” as long as the class somewhere inside (i.e. a descendent) of an ordered list. Notice that the word “item” is not highlighted because, even though it’s inside “.goofy,” it’s not a direct child. Only “goofy” is a direct child of “.goofy.” Maybe we should call it “goofy jr.”
  • $('li + li > a[href$=pdf]') gets all links ending in “pdf” that are children of any list item that has another list item as its previous sibling. It won’t get the first list item’s silly.pdf because that list item has no other list items before it.
  • $('span:hidden') gets any span element that is hidden.

Note: The selectors used for the toggle buttons are identical to the ones shown next to each button, except that they are preceded by $('#jqdt').find to target the highlighting.

jQuery’s selector expressions cover the full range of CSS 1-3, along with basic XPath and a few jQuery-only expressions. For a complete list, visit jquery.com

Next time, I’ll explore jQuery functions such as .filter(), prev(), and siblings() that complement the above selector expressions to give you full DOM-traversing power!

comment feed

59 comments

  1. Nice concise example that should be very handle for people new to jQuery’s syntax.

  2. Juha Suni

    Excellent examples. Good for learning, and good for “pwoer of jQuery” -show-offs too.

  3. Also a good way to learn advanced CSS selectors!

  4. Hey, thanks a lot for the compliments.
    Chris, won’t it be nice to actually be able to use those advanced CSS selectors in our stylesheets, now the IE7 is out the door? :) Can’t wait until a large enough percentage of users have migrated from IE6 to put some of those nifty CSS rules to work without having to worry about IE ruining the fun. :)

  5. It would be lovely, Karl, but it’s never going to happen. I fear we are stuck with IE6 forever. Only 23% of web users are running XP SP2, the only platform on which IE7 may be installed. Even when Vista (where IE7 is native) goes live, it’s unlikely to move IE7 use above legacy systems running IE6 in the forseeable future. The best we can hope for is a continued stream of one-way conversions to Firefox.

    • Marc Pettifer

      I think you misunderstood the stats. Yes 23% and rising run XP SP2, so you’ve taken that to assume that the other 77% all use IE6 , Lol!

      A few very popular web apps have already dropped support for IE6 and netmag has started a crusade for all designers to band together and force people to drop it.

      I for one, on my own projects, have dropped support for IE6, people who carry on supporting it , like a loving mother supports a badly behaved child, are only lengthening the time it will be use, as web developers and designers its within our power to force people to upgrade.

      IE6 ruins the user experience for others and wastes our time and money, its insecure, doesn’t work as intended and just plain rubbish.

  6. Chris, you make a good point, and I’m certainly not holding my breath. My comment did seem a little too eager, I suppose. Still, “never” and “forever,” I think, are as overly pessimistic as my comment was overly optimistic. After all, (almost) nobody bothers to support IE4 anymore, and fewer and fewer are supporting IE5.0.

    So, we sit and wait and hope and pray that people switch to Firefox or Opera — or at least IE7. In the meantime, conditional comments are my new best friend.

  7. How would you accomplish this with hover instead of click?

  8. William, to target any of these selectors on hover, you would use the .hover() method. For example:
    $("hovered_element").hover(function() {
    // Stuff to do when the mouse enters the element;
    }, function() {
    // Stuff to do when the mouse leaves the element;
    });

  9. Thank you! That little bit of information has really helped me move forward in learning jQuery. Great site! Please, keep up the posting.

  10. Very nice! I was ripping my hair out trying to get the id of the first div with a specific class. Your example of $(‘li:lt(3)’) did the trick. I simply used the following:

    var firstdiv = $(‘div.myclass:eq(0)’).id();

    Thank you!

  11. Hey DePaul, Glad you got it working. By the way, if you plan to switch to jQuery 1.1 when it’s released, you’ll need to use .attr('id') instead of .id(), unless you use the compatibility plugin.

  12. Lidocain

    Nice post, but …
    This part of code :

    $('#show-alert').click(function() {
    $('<div class="quick-alert">Alert! Watch me before it\'s too late!</div>') .insertAfter( $(this) );
    }

    should be AVOIDED as is. Inserting HTML code like this is really ugly, it’s a lot better to use the DOM methods :

    $('#show-alert').click(function() {
    var oDIV = document.createElement('div');
    oDiv.className = 'quick-alert';
    oText = document.createTextNode("Alert ! Watch me before it's too late !");
    $(oDiv).append(oText);
    $(oDiv).insertAfter(this);
    }

    Or, with the DOMCreate plugin for jQuery :

    $('#show-alert').click(function() {
    var oDiv = jQuery.create('div', {'class':'quick-alert'}, ["Alert ! Watch me before it's too late !"]});
    $(this).after(oDiv);
    }

  13. Stefan

    Regex selector please :)

  14. wolfwood

    What’s the code for selecting the external link?

  15. Stefan, my powers of influence are very limited when it comes to feature requests. You might want to check out the jQuery Development Google Group for previous threads regarding regular expression selectors.

    Wolfwood, if none of your internal links use a fully qualified URL (one beginning with “http”), you could do it this way: $('a[@href^=http]'). If you’re not sure about how the href is written for every internal link, you could add a .not() method, like so: $('a[@href^=http]').not('[@href*=mysite.com]'), where “mysite.com” is your domain.

  16. Asle

    I am wondering about this. How do I get the value of the attribute here on the main . I have a click event on the and I want to get the “id” to submit a URL. In this example I want to send the link “?m=delete&id=5″

    
    Special tan
    10-10-2007
     Delete
    

    I want to generate an alert when the user clicks on the button. I want to grab the “id” of the parent and the value of the with class=”title”

    
    $("button.negative").click(function() {
    	 var qid = $(this).parent("tr").attr("id");
    	 var tid = $(this).parent("tr"):("td.title").text();
    	 return confirm('Are you sure you want to delete "' + qid +'"!');
    	 // send the user to "?m=del&id=xx "
       })
    
  17. Asle

    Sorry, table got messed up. Here is the table cells:

    
    <tr id="5">
    <td class="title">Special tan</td>
    <td>10-10-2007</td>
    <td><button type="button" class="button negative"><img src="icons/cross.png" alt=""/>
    Delete</button></td>
    </tr>
    
  18. Hi Asle,

    Looks like you need to change .parent() to .parents() and then tweak the “tid” line a bit. Give this a try:

    	 var qid = $(this).parents("tr:first").attr("id");
    	 var tid = $(this).parents("tr:first").find("td.title").text();

    Note: I also changed “tr” to “tr:first” in case you have nested tables.

  19. Asle

    Thanks, that solved it and gave me a better understanding of traversing!

  20. Asle

    Refering to your answer to Stefan, I want to submit a link after checking a form. It seems with jQuery I do not have to have <a> to make a link. I have a button in my last post. I need a confirm before sending the link. Should I have the button as a link or do it this way?

    
    $("button.negative").click(function() {
    	 var qid = $(this).parents("tr:first").attr("id");
    	 var tid = $(this).parents("tr:first").find("td.title").text();
     	return confirm('Are you sure you want to delete"' + tid +'"?');
    	 location ="?m=del&Qid="+qid;
       })
    

    So answering yes would send a link to the same page with params. But the page is not loaded when I use the “return confirm” statement.

  21. Hi Mike,

    Part 2 has been out for a while. :)

    To select all elements with a particular class unless they have a specific descendant element, you could do this: $('.some-class:not(:has(someElement))')

    If you need to remove elements only based on their direct children (rather than any descendant), then you could do this:

    $('.some-class').filter(function() {
      return !$(this).children('someElement').length;
    })
  22. Tester

    This is only a TEST

  23. How do you access the selectors on a parent page: IE I want to send selected checkbox values, from a window opened by javascript back to a textarea element on the parent page.?

    thanks

    sas

  24. Florian

    How would I access value 1, 2 and 3 in href? Right now to make it easy I have
    stored my different values in id, in name and title attribute but that’s somehow
    an abuse.

    [a class="test" href="javascript:myFunction(value1,value2,value3)"]

    thx

  25. nice example. we can learn jquery easily by these type of examples. thanku

  26. Anyone (or @Lidocain) Why is it “Inserting HTML code [via method here] really ugly”? And why is it “a lot better to use the DOM methods”?

    The example you say “should be avoided” is much less code and simpler to read.

  27. dwigg

    Great article. Using it I have managed to create an application that manipulates the DOM. How would any amendments such as things I may have appended be ‘saved’ or ‘exported’ so that any changes I have made will be permanent?

  28. Hi dwigg,
    You can use ajax to send the new additions to the server.

  29. lidiexy

    Great article…
    Hi to all,
    I want to know, how get the pair [key=value] in this anchor:

         <a href='#?key=value&key1=value' id='myanchor'>text</a>
    

    Best regards

  30. Martin

    I have being searching for days for a way to find an element with a given class. Is that possible?

    For example: find all P with font-weight:bold. Or all DIV with background-color: yellow

    I know I can use the filter() function, but is it possible using a selector? If not, this would be a nice new feature!

    Thanks,
    Martin

  31. Martin

    Good stuff here!

    I wonder, is it possible to find an element by css, such as color?
    This does not work, though: $(“div[color='red']“).

    I know I can use a filter for this, but is it possible to do it with a selector only?

    Regards,
    Martin

  32. Nice tutorial! Thanks for sharing ;)

  33. EricBrown

    how would i grab everything whos name element starts with “bob”
    This will get all inputs, but how do i get everything, input or not?

    $(“input[@name^=bob]“).css(“border”, “3px solid red”);

    Also this seems to work wtih jquery 1.2.6 but not with 1.3.2

    Thanks,
    Eric-

  34. EricBrown

    Very cool,

    One question, it works in 1.2.1 but in 1.3.2 ^= and *= dont’ seemt o work,
    do you know what the new syntax is?

    Thanks,

    Eric-

    • Hi Eric,

      Thanks for the note. I just updated the post to reflect the change in jQuery’s attribute selector syntax. Up to jQuery 1.1.4, attributes were selected with [@attribute], but in jQuery 1.2.x versions the “@” was deprecated, and as of jQuery 1.3 it was removed completely. Try those examples again without the “@” symbol.

  35. VERY useful. I used this today and it was exactly what I needed. Thank you for sharing :)

  36. Mark

    Hello, I’d like to be able to toggle the background color between two links. So when you click one, the background turns yellow and if you click the next, it turns yellow and ‘deselects’ the previously clicked link’s background color. I haven’t been able to wrap my brain around this. If anyone has a suggestion I would be very grateful.

  37. Hi,

    Nice Article, Nice examples.

    The example “should be avoided” is really less code and simpler to read.

    Thanks

  38. LTrem
    <td id="test">
      <div>
        blabla
      </div>
      <div class="ulError" style="margin: 0px 0px 0px 0px;"></div>
    </td>
    

    I try to access the div with class “ulError” without success.

    I tried those :

    $(‘#test:eq(1)’)…. didn’t worked.
    $’#test > .ulError’)… didn’t worked.

    How can I get the div from the TD #test ?

  39. poupouille

    Hi thank you very much for this article (and the feedback you provide to people).
    Written more than 3 years ago, and still one of the best doc of this sort: geat job.
    Bye
    JC

  40. Why Jquery And not Spry which Adobe tries to push it? Why Adobe for example dont use jQuery and made me use Spry for 2 years untill i decided to switch and since then i`m doing less work.

  41. anonymous

    There’s a bug in the text:

    $(‘li:not(.goofy)’) gets list items 1, 2, and 4, because they’re not “goofy.”

    It should be:

    $(‘li:not(.goofy)’) gets list items 1, 3, and 4, because they’re not “goofy.”

  42. How to get the domain names from sites like http://image.co.uk/ or http://www.pictures.com/ ?
    Is is possible with jQuery? In JavaScript there isn’t such thing as subdomain. With location.host oder hostname can’t get it.

    In this example i want to get IMAGE and PICTURES

    thx, pete

  43. Great tutorial, make things easier, thanks for sharing!
    It would be so much appreciated if i could find here a small tutorial on how to make a cost estimator with jquery? thanks.

  44. Great list of functions. I am using some of them on my website now! I like this better than the examples on jquery.api help site, because here I can always see more functions together on one page and can decide which ones will be helpful for the project. Thanks Karl!

  45. Wow, I’ve been struggling with only showing one hide element in a doc, finally came across this site and fixed it sharpish. If only the tutes on JQuery site could be so simple and detailed.
    Thanks for the hard work and help your providing to all of us out here :) Shabba

  46. Lalo

    hi, I have this html code:

    Inicio
    Páginas médicas
    Dentistas
    Temas
    Anunciese aqui

    I want to get all h1 how do I do it?
    I was trying this:
    var op = $(‘#buttonsWrapper h1′);
    but it doesn’t work, I think it’s because h1 is not a buttonsWrapper child but I don’t know how to do it.. can anyone help me?

    thanks!!

  47. Bill

    Fixed previous post
    I have a tricky one, I think….
    I’m trying to create a dynamic fancybox popup that retrieves it’s input fields from the parent page. The parent page has several tables in it with their own [Edit] buttons.
    Each Table section is encased by a div where class=”flds”.
    and each table uses the same class
    Like so….

    &ltdiv class=”flds”&gt
    &lttable class=”thisTable”&gt
    &ltinput type=”button” onclick=”getTheseForValues()” &gt
    &ltlabel for=”value1″&gtField 1&lt/label&gt
    &ltlabel for=”value2″&gtField 2&lt/label&gt
    &ltlabel for=”value3″&gtField 3&lt/label&gt
    &lt/table&gt
    &lt/div&gt

    &ltdiv class=”flds”&gt
    &lttable class=”thisTable”&gt
    &ltinput type=”button” onclick=”getTheseForValues()” &gt
    &ltlabel for=”value a”&gtField a&lt/label&gt
    &ltlabel for=”value b”&gtField b&lt/label&gt
    &ltlabel for=”value c”&gtField c&lt/label&gt
    &lt/table&gt
    &lt/div&gt

    Now, I want to return value 1, value 2, and value 3 when I click the button in the 1st section and return value a, value b, value c when I click the button in the 2nd section.

    I can’t figure it out. Any help would be appreciated.

    Thanks.

8 Pings

  1. [...] Learning jQuery » Blog Archive » How to Get Anything You Want – part 1 (tags: javascript jquery) [...]

  2. [...] How to get everything you want part 1 How to get everything you want part 2 jQuery Selectors [...]

  3. [...] How to Get Anything You Want – part 1 [...]

  4. [...] How to Get Anything You Want – part 1 [...]

  5. [...] How to Get Anything You Want – part 1 [...]

Sorry, but comments for this entry are now closed.