0plus1
0plus1

Reputation: 4555

Data attribute changed in the DOM but ignored by jQuery

I did a quick fiddle to show the issue: http://jsfiddle.net/nm3Ma/1/

Take this html:

<div class="myclass" data-number="1"></div>
<div class="myclass" data-number="2"></div>
<div class="myclass" data-number="3"></div>

and this js

$(".myclass").each(function(){      
    var number = $(this).data('number');
    if( number>1 )
    {
        $(this).attr('data-number', number-1 );
    }
    $('body').append($(this).data('number')+'<br/>'); 
});

The code actually changes the HTML to:

<div class="myclass" data-number="1"></div>
<div class="myclass" data-number="1"></div>
<div class="myclass" data-number="2"></div>

But it still prints:

1
2
3

Can someone explain what am I doing wrong? Thank you.

Upvotes: 1

Views: 135

Answers (1)

Arun P Johny
Arun P Johny

Reputation: 388436

jQuery uses an internal data structure to store the data values, the data-* attributes are used to initiate the data values if the key is not found in the internal structure. So when you read the value for the second time it is reading the value from the internal structure instead of the attribute, so changes made to the attribute will not be visible to it.

You need to use the setter version of .data() to set the data value

$(".myclass").each(function(){      
    var number = $(this).data('number');
    if( number>1 )
    {
        $(this).data('number', number-1 );
    }
    $('body').append($(this).data('number')+'<br/>'); 
});

Demo: Fiddle

Or use attr() to both read and write value

$(".myclass").each(function () {
    var number = $(this).attr('data-number');
    if (number > 1) {
        $(this).attr('data-number', number - 1);
    }
    $('body').append($(this).attr('data-number') + '<br/>');
});

Demo: Fiddle

Upvotes: 3

Related Questions