How to find the next element which has an ID attribute using jQuery

14,414

Solution 1

Try :

var nextSectionWithId = $(this).closest("section").nextAll("section[id]:first");

or

var nextSectionWithId = $(this).closest("section").nextAll("section[id]").filter(':first');

Fiddle

You cannot use next because next will look for a match only in the next element. So you can instead use nextAll combined with :first in the selector.

Update

You can use the first() method in jquery to fetch the first element in the collection as well which seems like a faster option.

var nextSectionWithId = $(this).closest("section").nextAll("section[id]").first();

Probably could be this reason:

Because :first is a jQuery extension and not part of the CSS specification, queries using :first cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. To achieve the best performance when using :first to select elements, first select the elements using a pure CSS selector, then use .filter(":first").

Coutesy @T.J. Crowder

Solution 2

Use .nextAll()

DEMO

var nextSectionWithId = $(this).closest("section").nextAll("section[id]")[0].id;

DEMO

var nextSectionWithId = $(this).closest("section").nextAll("section[id]").eq(0).attr('id');

DEMO

var nextSectionWithId = $(this).closest("section").nextAll("section[id]").attr('id');
Share:
14,414
Digbyswift
Author by

Digbyswift

.Net Developer based in Leeds, UK. I work mostly with MVC, Azure, NHibernate, Umbraco, ElasticSearch, Javascript, Lucene, EF and all that shabang. I'm also a black belt in karate.

Updated on June 22, 2022

Comments

  • Digbyswift
    Digbyswift almost 2 years

    When I click on a link, I need to find the next <section> that has an ID attribute and return its ID.

    So given the following markup and javascript, I would expect clicking on the link to write "section_3" to the console.

    <section id="section_1">
        <a href="#" class="findNext">Find</a>
    </section>
    <section></section>
    <section id="section_3"></section>
    <section id="section_4"></section>
    

    and

    $('a.findNext').click(function() {
        var nextSectionWithId = $(this).closest("section").next("section[id]");
        if (nextSectionWithId) {
            var sectionId = nextSectionWithId.attr('id');
            console.log(sectionId)
        }
    });
    

    But this doesn't work. I have set the code up here in jsFiddle.

    Any ideas why this is not working?

    • Kevin B
      Kevin B over 10 years
      .next doesn't search through all following siblings, it only look at the immediate next one. it's in the api docs.
    • marcellscarlett
      marcellscarlett over 10 years
      If a selector is provided, it retrieves the next sibling only if it matches that selector. Your next section doesn't have an id.
    • Digbyswift
      Digbyswift over 10 years
      Excellent, I obviously misinterpreted it to mean "the next one to match the criteria" not "the next if it meets the criteria".
    • T.J. Crowder
      T.J. Crowder over 10 years
      @Digbyswift: You're not the first, by far, to have made that assumption.
  • PSL
    PSL over 10 years
    I did not downvote, but reason could be that OP wants to find only the next element with the condition, not all of them. attr('id') works because it considers only the first element in the collection.
  • Liam
    Liam over 10 years
    nextAll returns a list not an individual element. You also need the :first selector
  • Liam
    Liam over 10 years
    That's better :) That said, it did seem to work, but the updated answer makes more sense.
  • Liam
    Liam over 10 years
    @T.J.Crowder, You found it? Isn't that your question :) Good to know!!
  • T.J. Crowder
    T.J. Crowder over 10 years
    Of course, the updated answer will throw an exception if there aren't any following siblings with ids, whereas .nextAll("section[id]").attr("id") will return the id of the first such sibling (if any) or undefined if none, rather than throwing. It's one of the few use-cases where using .attr("id") can actually make sense (unlike the common horror $(this).attr("id") one sees far too often :-) ).
  • T.J. Crowder
    T.J. Crowder over 10 years
    @Liam: Yes, it is. :-) I meant "I found" as in "I learned" (in this case, from Nick [and experimentation]).
  • Tushar Gupta - curioustushar
    Tushar Gupta - curioustushar over 10 years
    @T.J.Crowder Check the updated the answer used .eq(0) . Ty for telling me that :)
  • T.J. Crowder
    T.J. Crowder over 10 years
    @TusharGupta: There's zero reason to use .eq(0) if you're using attr as a getter. When attr (or prop, or css, or text, or html, ...) is used as a getter, it always looks only at the first element in the set. I don't know what the answer originally looked like, but if someone downvoted it for doing .nextAll(...).attr("id"), that was their bad, not yours.
  • PSL
    PSL over 10 years
    @T.J.Crowder Yeah probably let me add that as well... in the answer... :) Thanks!!
  • Tushar Gupta - curioustushar
    Tushar Gupta - curioustushar over 10 years
    @T.J.Crowder hahhah my 1st answer was that only but i got Down-vote on that .
  • T.J. Crowder
    T.J. Crowder over 10 years
    @TusharGupta: But note that the OP didn't say they wanted the value of the id. They said they wanted to find the section (to me that means the element, not the id value). So .nextAll("section[id]").first() or .nextAll("section[id]:first') as in PSL's answer.
  • Tushar Gupta - curioustushar
    Tushar Gupta - curioustushar over 10 years
    @T.J.Crowder Yes Sir . :)