jQuery 数据与属性?

Posted

技术标签:

【中文标题】jQuery 数据与属性?【英文标题】:jQuery Data vs Attr? 【发布时间】:2011-11-07 20:44:25 【问题描述】:

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

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

【问题讨论】:

请阅读:forum.jquery.com/topic/when-to-use-attr-vs-data @zzz 除了它似乎并没有真正回答这个问题......? 实际上是间接的。通过attr() 附加对象会导致内存泄漏(至少在IE 中),而使用data() 是安全的。他在回复中暗示了这一点,尽管他没有明确地站出来说出来。有关 jQuery 文档的更多信息(请参阅“附加说明”):api.jquery.com/attr @John B,仅供参考(尽管这是旧的),data-someAttribute 的数据属性无效;根据规范,只允许使用小写字母。使用大写字符会遇到无数奇怪的问题。 @AdrienBe 很多参考资料很容易通过搜索找到,但是因为我很无聊,所以给你:***.com/a/22753630/84473 【参考方案1】:

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

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

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

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

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

从上面继续我的例子:
$('#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 attributes are supposed to get ASCII-lowercased automatically、&lt;div data-foobar&gt;&lt;/div&gt;&lt;DIV DATA-FOOBAR&gt;&lt;/DIV&gt;&lt;dIv DaTa-FoObAr&gt;&lt;/DiV&gt;应该被视为相同,但为了获得最佳兼容性,应首选小写形式。

如果值与可识别的模式匹配,.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),但值得注意的是 hex was parsed incorrectly in jQuery versions before 1.7.2,并且从 jQuery 1.8 rc 1 开始不再解析为 Number

jQuery 1.8 rc 1 改变了自动转换的行为。以前,任何可以有效表示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

【讨论】:

@vitorbal,虽然这是真的,但.data() 返回的对象将设置连字符,因此$('#bar').data('foo-bar-baz') 可以工作,但$('#bar').data()['foo-bar-baz'] 可以不是。正是出于这个原因,我建议人们避免使用连字符形式。 好的,现在我明白你的意思了。不知道那个小细节,感谢您的更新:) @SableFoste,哪个链接? api.jquery.com/data 是该方法的正确链接,据我所知并没有改变。 我喜欢,foo,bar,baz,fizz,buzz 更多:D 爱每一行。【参考方案2】:

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

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

$.fn.data 将信息存储在ridiculously obscure 位置。它位于一个名为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() 或其他任何地方访问 检查时元素上不公开可见 可以是对象

【讨论】:

是的,我的主要问题是这些数据的存储位置,所以感谢您提供的信息! 另外.attr()是要走的路,如果之后你想使用 data 作为选择器(.data() 将找不到;请参阅codepen.io/anon/pen/EvawPV?editors=1011) 【参考方案3】:

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

jQuery .data() 方法允许您以一种安全的方式获取/设置任何类型的数据到 DOM 元素,从而避免循环引用,从而避免内存泄漏。

jQuery .attr() 方法只为匹配集合中的第一个元素获取/设置属性值。

示例:

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

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

【讨论】:

以上是关于jQuery 数据与属性?的主要内容,如果未能解决你的问题,请参考以下文章

DOM与BOM

Typescript 在我的指令中找不到范围或属性

jQuery选择器

Vue 指令大全

JQuery选择器总结

jQuery.animate() 函数详解