jQuery 数据与属性?

$.data$.attr在使用data-someAttribute时有什么区别?

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

我的理解是 $.data 存储在 jQuery 的 $.cache 中,而不是 DOM.因此,如果我想使用$.cache进行数据存储,我应该使用$.data.如果我想添加 HTML5 数据属性,我应该使用 $.attr("data-attribute", "myCoolValue").

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

推荐答案

如果你是从服务器向一个DOM元素传递数据,你应该在元素上设置数据:

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>

然后可以在 jQuery 中使用 .data() 访问数据:

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

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

但是,当您在 jQuery 中 使用 数据将数据存储在 DOM 节点上时,变量将存储在节点 object 上.这是为了适应复杂的对象和引用,因为将节点 element 上的数据存储为属性只会适应字符串值.

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.

$('#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":

<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

连字符键仍然有效:

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

但是 .data() 返回的对象将没有连字符键集:

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

出于这个原因,我建议避免使用 javascript 中的连字符键.

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

对于 HTML,请继续使用连字符形式.HTML 属性应该是 ASCII- 自动小写,所以 <div data-foobar></div>, <DIV DATA-FOOBAR></DIV><dIv DaTa-FoObAr></DiV>应该被视为相同,但为了获得最佳兼容性,应首选小写形式.

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.

.data() 方法也会执行一些基本的自动如果该值与可识别的模式匹配,则进行强制转换:

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

<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'));
});

如果您绝对必须将原始值作为字符串,那么您需要使用 .attr():

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

<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

这是一个人为的例子.对于存储颜色值,我曾经使用数字十六进制表示法(即 0xABC123),但值得注意的是 hex 已被解析在 1.7.2 之前的 jQuery 版本中不正确,并且从 jQuery 1.8 rc 1 开始不再被解析为 Number.

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 改变了自动转换的行为.以前,任何能够有效表示 Number 的格式都将转换为 Number.现在,数字值仅在其表示保持不变时才会自动转换.最好用一个例子来说明这一点.

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.

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

如果您打算使用其他数字语法来访问数值,请务必先将值转换为 Number,例如使用一元 + 运算符.

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.

+$('#foo').data('hex'); // 1000

相关文章