-5

In jQuery there is prev() method which returns the previous element in DOM. But my question is is there any possibility to get the previous element of some specific tag using $(this) keyword. I am trying $(this).prev() to select the 3rd element, but it doesn't work (at least on forms).

<div>
  <span class="item item-1">Item 1</span>
  <span class="item item-2">Item 2</span>
  <span class="item item-3">Item 3</span>
  <span class="item item-4">Item 4</span>
  <span class="item item-5">Item 5</span>
  <a href="#">Click</a>
</div>
Aayushi
  • 1,736
  • 1
  • 26
  • 48
  • 3
    If you use ordinal position in code like that, it will break if you change the DOM at all. Can't you refer to the item you want by class name, like `$(this).parent().find('.item-3')`? – Paul Abbott Jun 15 '17 at 21:40
  • *"It doesn't work"* could do with a bit more info. Does it return null? does it give `error $ not defined`? does it return an empty jquery object `$(this).prev().length==0`? does it return `item 5`? – freedomn-m Jun 15 '17 at 21:49
  • Are you doing `$(this).prev(".item-3")`? (`cause that won't work, if that's the case I'll explain why) – freedomn-m Jun 15 '17 at 21:49
  • please explain @freedomn-m – Aayushi Jun 16 '17 at 05:55
  • 2
    `.prev(".class")` will find the previous item, but **only** if it matches `class` - it the previous item does not match, then nothing it returned - it only looks at the one previous item, it does not keep looking until it finds one. It does: `.prevAll().first().filter(".class")` - most people expect it to do `.prevAll().filter(".class").first()` - which is subtly different. – freedomn-m Jun 16 '17 at 07:11

1 Answers1

1

I assumed you wanna select the 2nd item like this. Let's say you have two or three spans and you wanna select the second span, you need to use .prevAll() instead of .prev(). For your example, let me show you a working snippet:

$(function () {
  $("a").click(function () {
    console.log($(this).prevAll("span").eq(3).text());    // "Item 2"
    console.log($(this).prevAll(".item").eq(3).text());   // "Item 2"
    console.log($(this).prevAll(".item-2").text());       // "Item 2"
  });
});
div > * {display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <span class="item item-1">Item 1</span>
  <span class="item item-2">Item 2</span>
  <span class="item item-3">Item 3</span>
  <span class="item item-4">Item 4</span>
  <span class="item item-5">Item 5</span>
  <a href="#">Click</a>
</div>

Hope this works!

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
  • 1
    As a caveat, from the docs: *the elements are returned in order beginning with the closest sibling.* so be careful as (eg) `.eq(1)` may not be the one you're expecting. – freedomn-m Jun 15 '17 at 21:53
  • @freedomn-m Yea, I know this boss. Should I include it? – Praveen Kumar Purushothaman Jun 15 '17 at 22:02
  • Just adding to your already complete answer as it's non-obvious (I've never used .prevAll(class) (I would have used .prevAll().filter(class))) so just reading up on how worked with class and it's as you'd described (of course). Was just a little surprised about the order and thought it worth mentioning. I guess .prevAll(class)[1] would give a different element from .prevAll().filter(class)[1] Given that .eq is 0 based, with 5 items, .eq(2) would give the same value whether you went from the start or the end, also confusticating how it works. – freedomn-m Jun 15 '17 at 22:19
  • @freedomn-m You have described it very well, would you like to edit my answer and add it so that people might be benefited from the answer? At the same time they will know that you added it and it's not me (just wanted to give you due credits). – Praveen Kumar Purushothaman Jun 15 '17 at 22:26
  • @RokoC.Buljan Yep it works basically the opposite way! – Praveen Kumar Purushothaman Jun 15 '17 at 22:26