I think everybody, once in life, asked this question when dealing for the first time with jQuery (or similar frameworks):
When is better to use .data() and when is better .attr()?
The answer, isn't that simple and requires some explanations.
Let's see what the documentation of jQuery says about these 2 methods:
Store arbitrary data associated with the specified element and/or return the value that was set.
Get the value of an attribute for the first element in the set of matched elements or set one or more attributes for every matched element.
So what's the difference?
Basically the .attr() method has a direct influence on the DOM, so it'll get the data from the current HTML or change the HTML code if used to change an attribute value. Contrariwise, the .data() method will get the data from the internal cache and will change that data if a set is called, no DOM manipulation is made here. Another difference is that the .data() method requires a prefix 'data-' to work, for example, if I want to pass a data attribute named foo with bar as value I have to code:
$('#item').data('foo') to get the value.
As I said, data storage in the internal cache is not visible inside the DOM (for example inspecting the element using the browser), it means that if we have an attribute
data-foo and we change it using .attr(), its value retrieved with .data() will be the same as the original one. Ok, probably this part is a little confusing. I made a short code on JSFiddle that helps to understand it.
On my example there is a simple div:
<div id="item" data-foo="bar"> </div>
The div called
item has a
data-foo attribute that we'll edit in 2 ways, with .attr() and with .data().
The result is the following:
data-foo from data(): bar data-foo from attr(): bar - data changed to bar2 - data-foo from data(): bar2 data-foo from attr(): bar - <div id="item" data-foo="bar"> </div> - attribute changed to bar3 - data-foo from data(): bar2 data-foo from attr(): bar3 - <div id="item" data-foo="bar3"> </div>
As explained before, calling .data() to set something will not manipulate the dom file and calling .attr() to change the attribute will not change the data inside the internal cache.
This means that we cannot change an attribute using .attr() and the expecting that data returning from a .data() call.
Ok, now it's a bit more clear, but where .data() is better than .attr() or vice versa?
Now that the differences between .data() and .attr() are clear, we can understand when is better to use .attr() and when is better to use .data().
A good usage of the .data() call is when a value is passed to the client from the server that renders a page. For example, if we have a web app that needs to pass the value of
foo to the client, inside our rendering engine we'll have something like:
A good advantage of .data() over .attr() is that variables are stored in the node object, so we can store complex objects, not just string values. So this means that .data() is better way to store data when we have to get/set data relative to the current state of our application.
The .attr() call is better when we're dealing with changes on DOM tree that will have a direct influence on the markup, for example if we have to deal with a checkbox where the attribute 'checked' will actually show that checkbox as checked on UI. Example on JSFiddle.
I think that's it!