5

I have a list of products. Each product has a title and a review link. Currently the titles link directly to the individual product page, and the review links go elsewhere.

I'd like to use a jquery each loop to cycle through each li, take the href from the title (the first link), and apply it to the review link (the second link), so they both point to the product page.

Simplified code would be as follows:

<ul>
   <li><a href="product1.html">Product 1</a><a href="review1.html">Review 1</a></li>
   <li><a href="product2.html">Product 2</a><a href="review2.html">Review 2</a></li>
   <li><a href="product3.html">Product 3</a><a href="review3.html">Review 3</a></li>
</ul>

I thought it would be something like the following:

$("li").each(function(){
   var link = $("a:eq(0)").attr('href');
   $("a:eq(1)").attr("href", link);
});

But it always uses the same variable "link".

Can someone help me out?

5 Answers 5

11

I am passing this as an argument to define the context for each iteration of the each() loop. On each iteration, this refers to the element in question.

$("li").each(function(){
   var link = $("a:eq(0)", this).attr('href');
   $("a:eq(1)", this).attr("href", link);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Maybe you should explain that the second parameter you pass to $() (namely this here) defines the context of the selector.
3
$("li").each(function(){
   var link = $(this).find("a:eq(0)").attr('href');
   $(this).find("a:eq(1)").attr("href", link);
});

Comments

1

Another option that avoids having to use .each entirely is to pass a function as the second argument to .attr.

This works as follows:

$('li').find('a:nth-child(2)').attr('href', function(index, href) {
    return $(this).prev('a').attr('href'); // use previous sibling's href
});

Essentially, it will take each element that matches the selector, pass it through the function, and then set the href attribute to the result of that function. The function will be passed arguments: the first is its index in the matching set ($('li a:nth-child(2)') here), and the second is the current value of the attribute. In your particular case, you don't care about either, but often you will want to transform an attribute based on its current value, so it can be handy.

Which one to use is entirely a matter of taste, jQuery sets allow you to do a lotof things without having to directly use .each.

1 Comment

Cool, cheers for this - nice to see a different take on the same problem. That's why I love jquery :-)
0

Its because you are not using the li as the context of your a selection:

Try this:

$("li").each(function(){
    var a = $('a',this);
    var link = a.filter(":eq(0)").attr('href');
    a.filter(":eq(1)").attr("href", link);
});

Comments

0

Try:

 $("li").each(function(){
    var link = $("a:eq(0)", this).attr('href');
 $("a:eq(1)", this).attr("href", link);
  });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.