1

Possible Duplicate:
jquery find closest previous sibling with class

The code given below is working perfectly

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <div><span>Hello</span></div>

  <p class="selected">Hello Again</p>
  <p>And Again</p>
<script>$("p").prev(".selected").css("background", "yellow");</script>

</body>
</html>

But when i move .selected at the top(given below) then it is not working.Can anyone tell me how to make it to work for me and get the .selected element from .prev() method in the second case without manipulating html

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>

<p class="selected">Hello Again</p>//Moved to top
<div><span>Hello</span></div>

  <p>And Again</p>
<script>$("p").prev(".selected").css("background", "yellow");</script>

</body>
</html>
Community
  • 1
  • 1
  • 3
    Well, `.selected` is not the previous sibling of the other `p` element anymore, so it should not be surprising that it does not work. – Felix Kling May 14 '12 at 09:41
  • Yeah But i still want it to be selected –  May 14 '12 at 09:42
  • in case i have multiple selected then :first selector will give the nearest .selected to p or farthest .selected to p –  May 14 '12 at 09:45
  • Just try it ;) Btw, the title of the duplicate question is *" jquery find **closest** previous sibling with class"*. – Felix Kling May 14 '12 at 09:46
  • sorry to make so's database reductant –  May 14 '12 at 09:48

2 Answers2

4

You need to use .prevAll() instead of .prev(). The latter only checks the immediate predecessor which is div in your case. prevAll() however checks all prececessors so it will find your element. In case you have multiple predecessors matching your selector, use .prevAll('.selected').first() to get only the nearest one.

Demo: http://jsfiddle.net/ThiefMaster/GnEK5/

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • .prevAll(".selected:first") or .prevAll(".selected:last") –  May 14 '12 at 09:46
  • @AnkitGautam: That won't work. In both cases it matches the farthest element (which is rather odd): http://jsfiddle.net/ThiefMaster/GnEK5/1/ – ThiefMaster May 14 '12 at 09:49
  • Weird... `prevAll(".selected").first()` works though. Maybe a change in the jQuery implementation? But `:first` and `.first()` should work the same way... – Felix Kling May 14 '12 at 09:52
  • Mmh... the documentation of `:first` says: *"Selected elements are in the order of their appearance in the document"*, so maybe that's the reason... I updated the accepted answer in the other question. – Felix Kling May 14 '12 at 09:55
  • `:last` should work though.. which isn't the case in my example – ThiefMaster May 14 '12 at 09:58
  • Found the problem. Since all the elements are `p` elements, `prevAll` will get the union of all previous `.selected` elements. It works if you exclude them: http://jsfiddle.net/GnEK5/2/ or you have to iterate over them: http://jsfiddle.net/GnEK5/3/ – Felix Kling May 14 '12 at 10:18
  • The reason why `:first` and `:last` give the same results is probably due to how the selector is evaluated. The first `p` element has no previous siblings, but the second `p` has the first `.selected` element as prev sibling. jQuery can already stop here, since it found the first one and returns. But if you search for the last one, it has to evaluate for the last `p` element as well. This one has the second `.selected` and first `.selected` element as prev siblings and they are selected *in that order*. Hence the *last* element is the first `.selected` element again. Hope that makes sense. – Felix Kling May 14 '12 at 10:25
0

You can try

$('p').prevAll('.selected');
The System Restart
  • 2,873
  • 19
  • 28