jQuery: prev(<selector>) not working?
Asked Answered
R

4

20

I'm having trouble using prev() in jQuery where it's not selecting the right element.

My HTML structure is as follows:

<section id="about">
    ...
</section>
<hr>
<section id="contact">
    ...
</section>

The "active" section is #contact. I want to select the previous section skipping over the <hr>

active = active.prev('section') doesn't seem to be working. I think I may be reading the docs wrong...

If I take out the <hr> everything works beautifully. Any ideas on how to skip the <hr> on prev()?

TIA

Radiochemical answered 27/3, 2011 at 22:28 Comment(0)
A
28

I think I may be reading the docs wrong...

The API docs for .prev() give this description:

Description: Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.

So, the problem is that the hr is there and being searched by .prev(), then tested against the 'section' selector.


Any ideas on how to skip the <hr> on prev()?

You could call .prev() once to skip over that hr then call it again for the section:

active = active.prev().prev('section');

Or use .prevAll() and find the closest-preceding one (in case there are any other sections occurring before it):

active = active.prevAll('section').first();
Avlona answered 27/3, 2011 at 22:29 Comment(4)
Thanks! So prev() is a step to the next sibling no matter what the selector is? I was thinking prev('section') would match the first previous sibling that matched the selector. I used prevAll('section').first() it seems the closest sibling was at the beginning of the array. But still thank you for pushing me in the right direction! :)Radiochemical
I think you mean active = active.prevAll('section').first(); - see the documentation for prevAll which states "the elements are returned in order beginning with the closest sibling", i.e. they are in reverse order!Kelcie
@Kelcie is right. The answer should be updated. .first() is needed instead of .last().Metalline
Yeah, I even acknowledged it when the asker first pointed out the same thing in the very beginning. I finally updated the answer.Avlona
G
7

Use prevAll() instead

active = active.prevAll('section').first();

from jQuery documentation:

prev() => "Get the immediately preceding sibling" so it will only get the first element.

prevAll() => "Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector."

That's why when you remove the <hr>, it will work with prev().

Ghiselin answered 27/3, 2011 at 22:30 Comment(0)
P
1

Or try:

<section id="about">
    ...
<hr>
</section>
<section id="contact">
    ...
</section>
Posterior answered 27/3, 2011 at 22:31 Comment(0)
D
1

Just do

active = active.prevAll('section').eq(0);

seems that .prev() and .next() only select the nearest sibling, no matter if you provide a specific selector to it. If that selector doesn't match the sibling, .next('section').length will be 0. Therefore by using the above method, you get all preceding siblings matching your selector and with .eq(0) you select the closest one.

Dished answered 28/9, 2019 at 23:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.