The evil $.fn.data() method

Why you shouldn't use data() to access "data-" attributes.

by InfinitiesLoop

JavaScript

/*
jQuery's data() function allows you to associate data with DOM elements.
It's quite handy, because the data is attached to the DOM element, and 
it will naturally just "die" when the DOM element dies (assuming you
use jQuery's methods to kill the element).

This existed long before HTML5 "data-" attributes were introduced.
jQuery 1.5, way back in 2011, decided it would be clever if the existing data()
function would read "data-" attributes. It seemed like a good idea at
the time.

But I'm here to show you all the ways in which using data() to access
HTML5 "data-" attributes can trip you up. Because of these issues, I
will exclusively use .attr("data-x") to access information stored in a
"data-" attribute, never data(). data() is still useful, of course, just not
for getting data attributes.

Just pretend .data() has nothing to do with "data-" attributes what-so-ever.
You'll be better off.

To summarize:
attr() ===> data attributes
data() ===> getting and setting arbitrary data

Pretend they have nothing to do with each other! Here are some reasons why.

/*
======================================
.data() automatically converts "data-" attributes into data() properties.
======================================
*/
// seems legit.
log($('<div data-foo="something"></div>').data("foo")); // something

// lets see what happens if I change the attribute.
var $e = $('<div data-foo="before"></div>');
// get the value once...
var before = $e.data("foo");
// change the attribute value...
$e.attr("data-foo", "after");
// and then get the value again...
var after= $e.data("foo");
log(before, after); // before, before (expected before, after!)
/*
The first call to data() will enumerate all the data attributes on the element and convert them into data properties. This is a one-time process, effectively caching the data attributes. If you have code that modifies, adds, or deletes data- attributes, it won't be noticed by your data() consuming code. If the order of these operations...