问题描述
$.data
和 $.attr
在使用 data-someAttribute
时的用法有什么区别?
我的理解是 $.data
存储在 jQuery 的 $.cache
中,而不是 DOM.因此,如果我想使用$.cache
进行数据存储,我应该使用$.data
.如果我想添加 HTML5 数据属性,我应该使用 $.attr("data-attribute", "myCoolValue")
.
如果你从服务器向 DOM 元素传递数据,你应该在元素上设置数据:
<a id="foo" data-foo="bar" href="#">foo!</a>
然后可以在 jQuery 中使用 .data()
访问数据:
console.log( $('#foo').data('foo') );//输出bar"
但是,当您在 jQuery 使用数据的 DOM 节点上存储数据时,变量存储在节点 object 上.这是为了容纳复杂的对象和引用,因为将数据存储在节点 元素 上作为属性将仅容纳字符串值.
$('#foo').data('foo', 'baz');console.log( $('#foo').attr('data-foo') );//输出bar",因为属性从未改变console.log( $('#foo').data('foo') );//输出baz",因为值已在对象上更新
此外,数据属性的命名约定有一些隐藏的陷阱":
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
console.log( $('#bar').data('fooBarBaz') );//输出fizz-buzz",因为连字符自动以驼峰命名
带连字符的键仍然有效:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
console.log( $('#bar').data('foo-bar-baz') );//仍然输出fizz-buzz"
然而,.data()
返回的对象不会设置带连字符的键:
$('#bar').data().fooBarBaz;//作品$('#bar').data()['fooBarBaz'];//作品$('#bar').data()['foo-bar-baz'];//不起作用
出于这个原因,我建议避免在 javascript 中使用带连字符的键.
对于 HTML,请继续使用带连字符的形式.HTML 属性应该得到 ASCII- 自动小写,所以
、 和
<dIv Data-FoObAr></DiV>
应该被视为相同,但为了获得最佳兼容性,应该首选小写形式.
.data()
方法也将执行一些基本的自动如果值与识别的模式匹配,则进行强制转换:
$('#foo').data('str');//`"条"`$('#foo').data('bool');//`真`$('#foo').data('num');//`15`$('#foo').data('json');//`{fizz:['buzz']}`
这种自动投射能力对于实例化小部件非常方便.插件:
$('.widget').each(function() {$(this).widget($(this).data());//-或者-$(this).widget($(this).data('widget'));});
如果您绝对必须将原始值作为字符串,那么您需要使用 .attr()
:
</a><a id="bar" href="#" data-color="654321"></a>
$('#foo').data('color').length;//6$('#bar').data('color').length;//未定义,长度不是数字的属性$('#foo').attr('data-color').length;//6$('#bar').attr('data-color').length;//6
jQuery 1.8 rc 1 改变了自动转换的行为.以前,任何可以有效表示 Number
的格式都将转换为 Number
.现在,数字值只有在它们的表示保持不变时才会自动转换.最好用一个例子来说明这一点.
//前 1.8 后 1.8$('#foo').data('int');//1000 1000$('#foo').data('十进制');//1000 "1000.00"$('#foo').data('科学');//1000 "1e3"$('#foo').data('hex');//1000 "0x03e8"
如果您打算使用替代的数字语法来访问数字值,请务必先将值转换为 Number
,例如使用一元 +
运算符.
+$('#foo').data('hex');//1000
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")
.
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.
$('#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>
console.log( $('#bar').data('fooBarBaz') );
//outputs "fizz-buzz" as hyphens are automatically camelCase'd
The hyphenated key will still work:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
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:
<a id="foo"
href="#"
data-str="bar"
data-bool="true"
data-num="15"
data-json='{"fizz":["buzz"]}'>foo!</a>
$('#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()
:
<a id="foo" href="#" data-color="ABC123"></a>
<a id="bar" href="#" data-color="654321"></a>
$('#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
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>
// 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.
+$('#foo').data('hex'); // 1000
这篇关于jQuery 数据与 Attr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!