jQuery数据与Attr?


513

使用之间$.data$.attr使用时的用法有什么区别data-someAttribute

我的理解是$.data存储在jQuery的内部$.cache,而不是DOM。因此,如果要$.cache用于数据存储,则应使用$.data。如果要添加HTML5数据属性,则应使用$.attr("data-attribute", "myCoolValue")



14
@zzz除了似乎并没有真正回答问题...?
sdleihssirhc,2011年

2
实际上,它确实是间接的。通过使用附加对象attr()可能会导致内存泄漏(至少在IE中如此),而使用data()是安全的。尽管他没有明确表示出来,但他在答复中暗示了这一点。有关jQuery文档的更多信息(请参阅“其他说明”):api.jquery.com/attr

6
@John B,仅供参考(即使这很旧),的data属性data-someAttribute无效;根据规范,只能使用小写字母。使用大写字符,您会遇到无数奇怪的问题。
2013年

1
@AdrienBe通过搜索可以轻松找到很多参考文献,但是由于我很无聊,所以您去了:stackoverflow.com/a/22753630/84473
2014年

Answers:


748

如果要将数据从服务器传递到DOM元素,则应在该元素上设置数据:

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

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

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

但是,当您使用数据在jQuery中的DOM节点上存储数据时,变量将存储在node 对象上。这是为了容纳复杂的对象和引用,因为将数据存储在节点元素上作为属性将仅容纳字符串值。

从上面继续我的示例:
$('#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

同样,数据属性的命名约定也有一些隐藏的“陷阱”:

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

连字符的键仍然可以使用:

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"

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

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

因此,我建议避免在javascript中使用连字符键。

对于HTML,请继续使用连字符形式。HTML属性应该得到ASCII-小写自动,所以<div data-foobar></div><DIV DATA-FOOBAR></DIV><dIv DaTa-FoObAr></DiV>认为被视为是相同的,但最好的相容性下壳体形式应是优选的。

.data()如果该值匹配可识别的模式,则该方法还将执行一些基本的自动广播:

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']}`

这种自动广播功能对于实例化小部件和插件非常方便:

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

如果绝对必须具有原始值作为字符串,则需要使用.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

这是一个人为的例子。为了存储颜色值,我曾经使用数字十六进制表示法(即0xABC123),但值得注意的是,在1.7.2之前的jQuery版本中无法正确解析十六进制,并且Number从jQuery 1.8 rc 1起不再将其解析为a 。

jQuery 1.8 rc 1更改了自动广播的行为。之前,任何有效表示a的格式Number都将转换为Number。现在,只有数值表示形式保持不变时,才会自动广播数值。最好用一个例子说明。

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"

如果计划使用其他数字语法访问数字值,请确保将值强制转换为Number第一个值,例如使用一元运算+符。

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

17
@vitorbal,虽然这是正确的,但返回的对象.data()没有设置带连字符的格式,因此$('#bar').data('foo-bar-baz')可以工作,但$('#bar').data()['foo-bar-baz']不会。出于这个原因,我建议人们避免使用连字符形式。
zzzzBov 2012年

1
好,现在我明白你的意思了。不知道这么小的细节,感谢您的更新:)
vitorbal

1
@SableFoste,哪个链接?api.jquery.com/data是该方法的正确链接,据我所知没有更改。
zzzzBov

1
我喜欢,foo,bar,baz,fizz,嗡嗡声更多:D
Usman Younas

1
爱每一行。
Foo Bar

108

两者之间的主要区别在于其存储位置和访问方式。

$.fn.attr 将信息直接存储在元素中的属性中,这些属性在检查时可以公开看到,也可以从元素的本机API获得。

$.fn.data将信息存储在一个可笑的地方。它位于一个称为局部变量的封闭的局部变量上data_user,该局部变量是局部定义的函数Data的实例。无法从jQuery外部直接访问此变量。

数据集 attr()

  • 可从 $(element).attr('data-name')
  • 从访问element.getAttribute('data-name')
  • 如果该值是形式data-name也可以访问$(element).data(name)element.dataset['name']element.dataset.name
  • 经检查在元件上可见
  • 不能是对象

数据集 .data()

  • 访问.data(name)
  • 无法从.attr()其他地方访问
  • 经检查在元素上不公开可见
  • 可以是对象

2
是的,我的主要问题是该数据的存储位置,因此感谢您提供该信息!
Max Wilder

2
.attr()就是要走的路,如果事后你想使用的数据作为选择(.data()不会被发现;看到codepen.io/anon/pen/EvawPV?editors=1011
Kamafeather

1

您可以使用data-*属性嵌入自定义数据。这些data-*属性使我们能够在所有HTML元素上嵌入自定义数据属性。

jQuery .data()方法允许您以对循环引用(因此对内存泄漏)安全的方式获取/设置DOM元素的任何类型的数据。

jQuery .attr()方法的get / set属性值仅适用于匹配集中的第一个元素。

例:

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

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.