Last Updated: April 08, 2017
·
21.1K
· bontojr

When is better to use .data() or .attr()?

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:

.data()

Store arbitrary data associated with the specified element and/or return the value that was set.

and

.attr()

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: data-foo="bar"and call $('#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:

<div data-foo='<%=item.foo%>'>

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!

4 Responses
Add your response

I don´t understand you article because .data() and .attr() have different goals and can´t compete. With the data() function you can write and read user defined HTML5 data-* Attributes and with the attr() function you can write and read an "normal" attribute of an element.

.data("*") shorthand for .attr("data-*")

Your comparison should be:

.prop() VS attr()

over 1 year ago ·

I always use data() for 'data-' prefixed attributes. Save me a couple type :P

over 1 year ago ·

I feel that you are comparing apples with oranges here.

over 1 year ago ·

I made an account here just to comment on your post.
Thank you for the clarification. I am pretty new to javascript, so I fell in the trap of reading with .data() and setting with .attr(). I lost an hour on this, found the solution, but found it extremely confusing, annoying and frustrating.
I have little experience so I don't know why you cannot compare them (as the other users are saying), but when i looked up how to set my custom data atribute, the answers were pointing to .attr(), so I think the subject is not that clear to everyone and your article is really useful.
So thanks.

over 1 year ago ·