I learned something today thanks to my colleague Axel Hecht; the difference between $element.data('foo') and $element.attr('data-foo').

Basically, the .data() getter/setter is more powerful since it can do more things. For example:

<img id="image" data-number="42">
// numbers are turned to integers
assert($('#image').data('number') + 1 == 43);
// the more rudimentary way
assert($('#image').attr('data-number') + 1 == '421');

Integers is just one thing the .data() getter is able to parse. It can do other cool things too like booleans and JSON. Check out its docs

So, why would you NOT use .data()?

One reason is that with .data(name, value) the original DOM element is not actually modified. This can cause trouble if other pieces of Javascript depend on the value of a data- attribute further along in the page rendering process.

To see it in action check out: test.html

In conclusion: just be aware of it. Feel free to use the .data() getter/setter because it's way better but be aware of the potential risks.

Anthony - 10 June 2012 [«« Reply to this]
Actually the main difference is that data() is a way to store data for an element. This data is a JS variable. Which means reading from it and writing to it is faster cause it doesn't live in the DOM.

attr() on the other hand is a way to access attributes on nodes.

And it happens that data() will go check if the correspondent data-attribute exists when initialising the value.
Jurriaan Persyn - 11 June 2012 [«« Reply to this]
Be careful with .data(), it will also convert strings to numbers it shouldn't/can't convert, and silently fail.
If you put a 64-bit integer in a data html-attribute, jQuery will see it as a number (and thus cast it to a number), although Javascript doesn't support 64-bit integers. The result will be a completely different number, without any warning.

An example: If you have a twitter uid, save it in a data-twitter-uid-attribute and fetch that with jQuery.data('twitter-uid'), you'll get a faulty result, because a twitter uid exceeds Javascript's integer size limit.
Dominic Watson - 11 June 2012 [«« Reply to this]
Yes, the real risk is using attr('data-foo') to read the data. Better to always use .data('foo') to read it.
Peter Bengtsson - 11 June 2012 [«« Reply to this]
Check what Jurriaan wrote above. There are risks with reading with .data()
Dominic Watson - 11 June 2012 [«« Reply to this]
That's depressing (the comment was not visible when I posted). Good to know though. You might want to wrap the logic in your own getData() method should you really never want to directly expect that there is an html attribute. Something along the lines of (untested):

$.fn.getData( function( attr ){
 if ( this.attr( 'data-' + attr ) ) {
   return this.attr( 'data-' + attr );
 }

 return this.data( attr );
} );

This way, data could be set on the element as either an attribute or using .data() and you run no risk of expecting either one when you want to read the data back.
Dominic Watson - 11 June 2012 [«« Reply to this]
Or, indeed, a somewhat tidier version:

$.fn.getData( function( attr ){
 return this.attr( 'data-' + attr ) || this.data( attr );
} );


Your email will never ever be published