ChatGPT解决这个技术问题 Extra ChatGPT

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").

@zzz Except that it doesn't really seem to answer the question...?
Actually it does, indirectly. Attaching an object via attr() can lead to memory leaks (at least in IE), while using data() is safe. He hints at this in his reply though he doesn't explicitly come out and say it. More info on the jQuery docs (see the "Additional Notes"): api.jquery.com/attr
@John B, just FYI (even though this is old), the data attribute of data-someAttribute is invalid; per the spec, only lowercase is permitted. You'll run into a myriad of weird issues by using upper-case chars.
@AdrienBe Lot's of references easily found via search, but since I'm bored, here you go: stackoverflow.com/a/22753630/84473

z
zzzzBov

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

@vitorbal, while this is true, the object returned by .data() will not have the hyphenated form set, so $('#bar').data('foo-bar-baz') will work, but $('#bar').data()['foo-bar-baz'] will not. It's for this reason that I suggest that people avoid using the hyphenated form.
ok, now I see what you mean. Didn't know about that small detail, thanks for the update :)
@SableFoste, which link? api.jquery.com/data is the correct link for the method, and has not changed as far as I'm aware.
i like, foo,bar,baz,fizz,buzz more :D
Love every line.
T
Travis J

The main difference between the two is where it is stored and how it is accessed.

$.fn.attr stores the information directly on the element in attributes which are publicly visible upon inspection, and also which are available from the element's native API.

$.fn.data stores the information in a ridiculously obscure place. It is located in a closed over local variable called data_user which is an instance of a locally defined function Data. This variable is not accessible from outside of jQuery directly.

Data set with attr()

accessible from $(element).attr('data-name')

accessible from element.getAttribute('data-name'),

if the value was in the form of data-name also accessible from $(element).data(name) and element.dataset['name'] and element.dataset.name

visible on the element upon inspection

cannot be objects

Data set with .data()

accessible only from .data(name)

not accessible from .attr() or anywhere else

not publicly visible on the element upon inspection

can be objects


Yeah, my main question was where this data was stored, so thanks for that info!
Also .attr()is the way to go, if afterwards you want to use the data as selector (.data() will not be found; see codepen.io/anon/pen/EvawPV?editors=1011)
The fact that the values are stored by Jquery in a way that can only be accessed locally is an advantage when using .data () to manage dynamic values in the page, avoiding the problem that they can be modified by the browser inspector.
@LorenzoMagon - Even locally stored values can be modified by the browser inspector. There is nothing that the browser inspector cannot affect during runtime.
Y
Yogendra Chauhan

You can use data-* attribute to embed custom data. The data-* attributes gives us the ability to embed custom data attributes on all HTML elements.

jQuery .data() method allows you to get/set data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks.

jQuery .attr() method get/set attribute value for only the first element in the matched set.

Example:

<span id="test" title="foo" data-kind="primary">foo</span>

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");