1

Basically I've got two anchor tags separated by a div.

<a class="foo"></a>

<div class="count">0</a>

<a class="bar"></a>

and I'm doing something like this:

       var addClass = $(this).parent().children('a:first-child').addClass('new');

It will then add it to the first anchor tag like so:

<a class="foo new"></a>

I know using the nth:child selector is pretty expensive, so I was wondering if there was an easier way to select that previous anchor node, (while ignoring the second one).

bob_cobb
  • 2,229
  • 11
  • 49
  • 109

3 Answers3

3

You could do this

$(this).parent().children('a:eq(0)').addClass('new');

Learn more about :eq()

Alternatively, if there are no elements between the <a> and the <div>, you could do

$(this).prev('a');

Learn more about .prev()

maček
  • 76,434
  • 37
  • 167
  • 198
  • `prev('a')` will always return an empty set with the markup he's quoted; I know you said "if there are no elements between" but the point is there *are*. – T.J. Crowder Dec 04 '11 at 12:24
  • +1 for introducing me to :eq(), but T.J.'s works nicely and a little more elegant (not your fault, it's the nature of jQuery). – bob_cobb Dec 04 '11 at 12:26
  • @bob_cobb: Yes, it can be very useful -- but beware that here, it has the same issues as `:first` (the selector), see the question I linked from my answer for more on that (I found it very surprising that I was better off using `.first` [the function] after-the-fact rather than `:first` the selector [`:first` = `:eq(0)`]). – T.J. Crowder Dec 04 '11 at 12:27
  • 1
    @T.J.Crowder thanks for clarification. `prevAll` seems like the best way to go. Thanks for your other link, too :) – maček Dec 04 '11 at 12:29
2

I'd probably combine prevAll with first (or eq(0), since first just calls eq(0) — but I find first more readable):

$(this).prevAll("a").first().addClass("new");
// or
$(this).prevAll("a").eq(0).addClass("new");

prevAll returns all of the element's preceding siblings, in order starting with the closest sibling, and of course first / eq(0) reduces the set to the first element.

You might be tempted to use the :first selector with prevAll to avoid building up an unnecessary list of siblings, but to my surprise it works better to use first after-the-fact.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

How about:

$(this).siblings('a').eq(0).addClass(0);

Actually, if your structure is as simple as in your example, you can just do a simple:

$(this).prev().addClass(0);

jQuery's traversal methods give you lots of ways to get to any given destination.

N3dst4
  • 6,360
  • 2
  • 20
  • 34