6

I want to add progressive id to a series of elements on an unordered HTML list. I used the jQuery .each() method to get each <li> of the List and append a <span> inside each <li>. Then I added the ID attribute with index of each() as number.

$('#menu li ul li').each(function(i, e){
    $(this).append('<span class="arr"></span>');
    $(".arr").attr("id", "id_" + i);
});

Fiddle Demo

But I get id_3 for all elements. Why? What did I do wrong?

Thanks for any help!

2
  • What problem would adding the ids solve? Commented Apr 7, 2014 at 13:18
  • 1
    $(this).append('<span class="arr"></span>').attr("id", "id_" + i) or $(this).append('<span class="arr" id="id_'+i+'"></span>') will do what you want ... $(".arr").attr("id", "id_" + i) will set the same i to all arr class Commented Apr 7, 2014 at 13:18

6 Answers 6

7

It is because you are applying it to .arr globally, so overriding it every time.
You need to be more specific with adding it, by finding the .arr in you current li.

Change your code to be:

$('#menu li ul li').each(function(i, e){
    $(this).append('<span class="arr"></span>');
    $(this).find(".arr").attr("id", "id_" + i);
});
Sign up to request clarification or add additional context in comments.

Comments

4

As has been pointed out, $(".arr") targets every element with the arr class, so on the fourth iteration you update all such elements to the id_3 id.

You can limit the selection with $(".arr", this) or $(this).find(".arr"), but it would be easier to just turn the append around:

$('#menu li ul li').each(function(i, e){
    $('<span class="arr"></span>')
        .attr("id", "id_" + i)
        .appendTo(this);
});

That is, create the element first, set its id, then use .appendTo() instead of .append().

Or rather than calling .attr() you can pass the desired attributes directly to the $() function when you create your span:

$('#menu li ul li').each(function(i, e){
    $('<span></span>', {
        "class": "arr",
        "id": "id_" + i
    }).appendTo(this);
});

1 Comment

Thank you very much for your very comprehensive answer.
3

You are targeting a class when assigning the attribute. Every element you create is created with the same class so all items get assigned the same attribute. This code saves the newly created element to a variable called elem and then sets the attribute ID of that newly created element.

var elem = $(this).append('<span class="arr"></span>');
elem.attr("id", "id_" + i);

Comments

1

You need to scope your $(".arr").attr("id", "id_" + i); selector. Its currently pulling all the <span> tags each time. I'm guessing you have 4 total at this point, which is why they are all getting set to "id_3".

Added in $(this) to your selector.

$('#menu li ul li').each(function(i, e){ $(this).append('<span class="arr"></span>'); $(".arr", this).attr("id", "id_" + i); });

Modified Fiddle: http://jsfiddle.net/NZgyD/2/

1 Comment

Wouldn't $(".arr",this) do the trick? No need to wrap this with $().
0

you can do it this way

$('#menu li ul li').each(function(i, e){
    $(this).append('<span id="id_' + i + '" class="arr"></span>');
});

Comments

-1

because $(".arr") is selector for multiple items

2 Comments

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.
@Łukasz웃Lツ - It answers the question (which was "Why? What did I do wrong?"), just not in a very comprehensive way. But for some people just knowing what they did wrong would be enough for them to fix the problem themselves...

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.