Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Data vs Attr?

What is the difference in usage between $.data and $.attr when using data-someAttribute?

My understanding is that $.data is stored within jQuery's $.cache, not the DOM. Therefore, if I want to use $.cache for data storage, I should use $.data. If I want to add HTML5 data-attributes, I should use $.attr("data-attribute", "myCoolValue").

like image 905
John B Avatar asked Aug 31 '11 18:08

John B


People also ask

Is ATTR deprecated in jQuery?

attr() deprecated/removed for use with "checked" and "disabled" properties. Many sites now use various means to update their version of jQuery to a later version than 1.4, the version in Drupal 7. jQuery deprecated (version 1.6) and removed (version 1.9) the use of .

What does attr in jQuery do?

jQuery attr() Method The attr() method sets or returns attributes and values of the selected elements. When this method is used to return the attribute value, it returns the value of the FIRST matched element.

What is jQuery data?

The data() is an inbuilt method in jQuery which is used to attach data or get data for the selected elements. Syntax: $(selector). data(para1); Parameter : It accepts an optional parameter “para1” which specifies the name of the data to retrieve for the selected element.

How set data attribute in jQuery?

To set an attribute and value by using a function using this below syntax. $(selector). attr(attribute,function(index,currentvalue)) ; To set multiple attributes and values using this below syntax.


1 Answers

If you are passing data to a DOM element from the server, you should set the data on the element:

<a id="foo" data-foo="bar" href="#">foo!</a> 

The data can then be accessed using .data() in jQuery:

console.log( $('#foo').data('foo') ); //outputs "bar" 

However when you store data on a DOM node in jQuery using data, the variables are stored on the node object. This is to accommodate complex objects and references as storing the data on the node element as an attribute will only accommodate string values.

Continuing my example from above:
$('#foo').data('foo', 'baz');  console.log( $('#foo').attr('data-foo') ); //outputs "bar" as the attribute was never changed  console.log( $('#foo').data('foo') ); //outputs "baz" as the value has been updated on the object 

Also, the naming convention for data attributes has a bit of a hidden "gotcha":

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a> 
JS:
console.log( $('#bar').data('fooBarBaz') ); //outputs "fizz-buzz" as hyphens are automatically camelCase'd 

The hyphenated key will still work:

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a> 
JS:
console.log( $('#bar').data('foo-bar-baz') ); //still outputs "fizz-buzz" 

However the object returned by .data() will not have the hyphenated key set:

$('#bar').data().fooBarBaz; //works $('#bar').data()['fooBarBaz']; //works $('#bar').data()['foo-bar-baz']; //does not work 

It's for this reason I suggest avoiding the hyphenated key in javascript.

For HTML, keep using the hyphenated form. HTML attributes are supposed to get ASCII-lowercased automatically, so <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>, and <dIv DaTa-FoObAr></DiV> are supposed to be treated as identical, but for the best compatibility the lower case form should be preferred.

The .data() method will also perform some basic auto-casting if the value matches a recognized pattern:

HTML:
<a id="foo"     href="#"     data-str="bar"     data-bool="true"     data-num="15"     data-json='{"fizz":["buzz"]}'>foo!</a> 
JS:
$('#foo').data('str');  //`"bar"` $('#foo').data('bool'); //`true` $('#foo').data('num');  //`15` $('#foo').data('json'); //`{fizz:['buzz']}` 

This auto-casting ability is very convenient for instantiating widgets & plugins:

$('.widget').each(function () {     $(this).widget($(this).data());     //-or-     $(this).widget($(this).data('widget')); }); 

If you absolutely must have the original value as a string, then you'll need to use .attr():

HTML:
<a id="foo" href="#" data-color="ABC123"></a> <a id="bar" href="#" data-color="654321"></a> 
JS:
$('#foo').data('color').length; //6 $('#bar').data('color').length; //undefined, length isn't a property of numbers  $('#foo').attr('data-color').length; //6 $('#bar').attr('data-color').length; //6 

This was a contrived example. For storing color values, I used to use numeric hex notation (i.e. 0xABC123), but it's worth noting that hex was parsed incorrectly in jQuery versions before 1.7.2, and is no longer parsed into a Number as of jQuery 1.8 rc 1.

jQuery 1.8 rc 1 changed the behavior of auto-casting. Before, any format that was a valid representation of a Number would be cast to Number. Now, values that are numeric are only auto-cast if their representation stays the same. This is best illustrated with an example.

HTML:
<a id="foo"     href="#"     data-int="1000"     data-decimal="1000.00"     data-scientific="1e3"     data-hex="0x03e8">foo!</a> 
JS:
                              // pre 1.8    post 1.8 $('#foo').data('int');        //    1000        1000 $('#foo').data('decimal');    //    1000   "1000.00" $('#foo').data('scientific'); //    1000       "1e3" $('#foo').data('hex');        //    1000     "0x03e8" 

If you plan on using alternative numeric syntaxes to access numeric values, be sure to cast the value to a Number first, such as with a unary + operator.

JS (cont.):
+$('#foo').data('hex'); // 1000 
like image 91
zzzzBov Avatar answered Oct 13 '22 02:10

zzzzBov