3

Was going through jQuery documentation and found something I don't quite understand, yet ) Let's say on the page I have a list like this:

<ul id='list0'>
    <li>list item 1<b></b></li>
    <li>list item 2<b></b></li>
    <li>list item 3<b></b></li>
    <li>list item 4<b></b></li>
</ul>

When I run this code

$('#list0 li').attr('id', function(i) {
    return (i + 1) % 2 ? 'odd' : 'even';
}).each(function() {
    $('b', this).text(' -> ' + this.id);
});

I get output of

  • list item 1 -> odd
  • list item 2 -> even
  • list item 3 -> odd
  • list item 4 -> even

Everything works as expected and each <li> inside of <ul> gets an id of odd or even. When I use each() to set content inside <b> I can get an id of <li> using this.id.

Question is, why doesn't this work when I use a different <li> attribute rather than id?

$('#list0 li').attr('foo', function(i) {
    return (i + 1) % 2 ? 'odd' : 'even';
}).each(function() {
    $('b', this).text(' -> ' + this.foo);
}); 

Results in

  • list item 1 -> undefined
  • list item 2 -> undefined
  • list item 3 -> undefined
  • list item 4 -> undefined

Even when foo attribute of each <li> still sets to even or odd somehow this time I can't get foo inside of each() with this.foo.

I use jQuery 1.10.2.

Thank you.

  • is the question retorical or do you have a problem ? If so, let us know what the goal is, as attempting to loop using attributes is not the right tool, think of .attr() as a getter or a setter. – Rob Sedgwick Jan 04 '14 at 11:36
  • @RobSedgwick Yes, it's purely rhetorical. I confused node attributes and properties. –  Jan 04 '14 at 11:40
  • 1
    btw the reason why you are able to loop (.each() ) is because jquery returns the initial selection back ( for chaining ). There are no restrictions on getting attributes, but good to use 'data-' for custom ones, ie - ' data-foo="" ' – Rob Sedgwick Jan 04 '14 at 11:40
  • :) ok, well if retorical, you answer is , not to use .attr() this way, the second param is the setter - it is just evaluating the function you are sending to see if it returns a value to set the attribute as. consider $("img").attr("src",function() { return "/test.gif"; }); – Rob Sedgwick Jan 04 '14 at 11:44

2 Answers2

2

Two things to notice here:

First of all ids are unique, in practice you should only have one element with a given id at most. So your first code example is something you shouldn't do.

Elements do not have afoo property, and you need to access it using this.getAttribute("foo") or $(this).attr("foo").

So:

('#list0 li').attr('foo', function(i) {
    return (i + 1) % 2 ? 'odd' : 'even';
}).each(function() {
    $('b', this).text(' -> ' + this.getAttribute('foo'));
}); 

On a side note - you should probably not have sequential list IDs like list0, list1 and so on since they prove problematic. You should also consider storing arbitrary data in JavaScript objects and not on the DOM if you were doing that.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
1

A DOM node may have attributes and properties. But they are really two different things.

for example

using class Attribute and className Property

For reference

http://javascript.info/tutorial/attributes-and-custom-properties

rajesh kakawat
  • 10,826
  • 1
  • 21
  • 40