jQuery .data() 不起作用,但 .attr() 起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8707226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 10:55:46  来源:igfitidea点击:

jQuery .data() does not work, but .attr() does

jquery

提问by Ian Davis

Forgive me for not being more specific on this. I have such a strange bug. After the doc loads, I loop some elements that originally have data-itemname="", and I set those values using .attr("data-itemname", "someValue").

请原谅我没有在这方面更具体。我有一个如此奇怪的错误。文档加载后,我循环了一些最初具有 的元素data-itemname="",并使用.attr("data-itemname", "someValue").

Issue: When I later loop thru those elements, if I do elem.data().itemname, I get "", but if I do elem.attr("data-itemname"), I get "someValue". It's like jQuery's .data()getter only gets elements that are set initially to contain some value, but if they are originally empty, and later set, then .data()doesn't get the value later on.

问题:当我稍后循环遍历这些元素时,如果我这样做elem.data().itemname,我得到"",但如果我这样做elem.attr("data-itemname"),我得到"someValue". 这就像 jQuery 的.data()getter 只获取最初设置为包含某个值的元素,但如果它们最初为空,然后设置,则稍后.data()不会获取该值。

I've been trying to recreate this bug but have not been able to.

我一直在尝试重新创建此错误,但未能成功。

Edit

编辑

I have recreated the bug! http://jsbin.com/ihuhep/edit#javascript,html,live

我已经重新创建了错误!http://jsbin.com/ihuhep/edit#javascript,html,live

Also, snippets from above link...

此外,来自上述链接的片段...

JS:

JS:

var theaters = [
    { name: "theater A", theaterId: 5 },
    { name: "theater B", theaterId: 17 }
];

$("#theaters").html(
    $("#theaterTmpl").render(theaters)
);

// DOES NOT WORK - .data("name", "val") does NOT set the val
var theaterA = $("[data-theaterid='5']");
theaterA.find(".someLink").data("tofilllater", "theater5link"); // this does NOT set data-tofilllater
$(".someLink[data-tofilllater='theater5link']").html("changed link text"); // never gets changed

// WORKS - .attr("data-name", "val") DOES set val
var theaterB = $("[data-theaterid='17']");
theaterB.find(".someLink").attr("data-tofilllater", "theater17link"); // this does set data-tofilllater
$(".someLink[data-tofilllater='theater17link']").html("changed link text");

HTML:

HTML:

<body>
    <div id="theaters"></div>
</body>

<script id="theaterTmpl" type="text/x-jquery-tmpl">
    <div class="theater" data-theaterid="{{=theaterId}}">
        <h2>{{=name}}</h2>
        <a href="#" class="someLink" data-tofilllater="">need to change this text</a>
    </div>
</script>

回答by leepowers

I ran into a similar "bug" a few days ago when working with .data()and .attr('data-name')for HTML5 data attributes.

有工作时,我遇到了一个类似的“错误”前几天.data().attr('data-name')对HTML5的数据属性。

The behavior you're describing is not a bug, but is by design.

您描述的行为不是错误,而是设计使然。

The .data()call is special - not only does it retrieve HTML5 data attributes it also attempts to evaluate/parse the attributes. So with an attribute like data-myjson='{"hello":"world"}'when retrieved via .data()will return an Objectwhile retrieval via .attr()will return a string. See jsfiddle example.

这个.data()调用很特别——它不仅检索 HTML5 数据属性,还尝试评估/解析这些属性。因此,对于像data-myjson='{"hello":"world"}'检索时这样的属性.data()将返回Object而检索时.attr()将返回一个字符串。请参阅 jsfiddle 示例。

Since .data()does extra processing jQuery stores the results of attribute evaluation in $.cache- after all, once a data attribute has been evaluated it would be wasteful to re-evaluate on every .data()call - especially since data variables can contain complex JSON strings.

因为.data()额外的处理 jQuery 将属性评估的结果存储在$.cache- 毕竟,一旦评估了数据属性,在每次.data()调用时重新评估将是浪费的- 特别是因为数据变量可能包含复杂的 JSON 字符串。

I said all that to say the following: After retrieving an attribute via .data()any changes made by .attr('data-myvar', '')will not be seen by subsequent .data()calls.Test this out on jsfiddle.

我说了这么多是为了说明以下内容:通过.data()所做的任何更改检索属性后.attr('data-myvar', ''),后续.data()调用将看不到。在 jsfiddle 上测试一下。

To avoid this problem don't intermix .dataand .attr()calls.Use one or the other.

为了避免这个问题,不要混用.data.attr()调用。使用其中之一。

回答by T.J. Crowder

This is the result of a misunderstanding: datais NOT an accessor for data-*attributes. It's both more and less than that.

这是误解的结果:datais NOT a accessor for data-*attributes。它比这更多和更少。

datais an accessor for jQuery's data cache on the element. That cache is initializedfrom data-*attributes if there are any present, but datanever writesto the attributes, nor does changing the attribute change the data cache after initialization:

data是元素上 jQuery 数据缓存的访问器。如果存在任何属性,则该缓存从属性初始化data-*,但data永远不会写入属性,更改属性也不会在初始化后更改数据缓存:

const div = $("[data-example]");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
console.log('Using div.data("example", "updated")');
div.data("example", "updated");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
<div data-example="initial value"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

dataalso massages what it finds in various ways, guessing at data types, making data("answer")on an element with data-answer="42"a number, not a string, or even parsing things as JSON if they look like JSON:

data还以各种方式处理它发现的内容,猜测数据类型,data("answer")使用data-answer="42"数字而不是字符串制作元素,或者甚至将事物解析为 JSON(如果它们看起来像 JSON):

console.log(typeof $("[data-answer]").data("answer"));
console.log(typeof $("[data-json]").data("json"));
console.log(typeof $("[data-str]").data("str"));
<div data-answer="42"></div>
<div data-json='{"answer":42}'></div>
<div data-str="example"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

If you want to use the attributes (both reading and setting them), use attr, not data. attrisan accessor for attributes.

如果要使用属性(读取和设置它们),请使用attr,而不是dataattr属性的访问器。

回答by Marc B

That's because the attribute's name is data-itemname. You cannot use -in the shorthand obj.attributenotation (obj.data-itemname would be intepreted as "obj.data minus itemname").

那是因为属性的名称是data-itemname. 您不能-在速记obj.attribute符号中使用(obj.data-itemname 将被解释为“obj.data 减去 itemname”)。

回答by bevacqua

Why don't you just use .data()everywhere?

你为什么不.data()到处使用?

You can also declare default values inline on the HTML, which is fine too.

您还可以在 HTML 上内联声明默认值,这也很好。

<span data-code="pony">text</span>

and

$("span").data("code") == "pony" // true

if you want to change it you just do

如果你想改变它,你就去做

$("span").data("code", "not-a-pony");

and to remove it altogether you could invoke

并完全删除它,你可以调用

$("span").removeData("code");

you should really try and avoid using .attr("data-*"), I don't know why you'd want to do so anyways.

你真的应该尽量避免使用.attr("data-*"),我不知道你为什么要这样做。

回答by Elmar H?finghoff

.attr("data-itemname", "someValue")modifies the DOM.

.attr("data-itemname", "someValue")修改 DOM。

.data("itemname", "someValue")modifies the jQuery cache.

.data("itemname", "someValue")修改 jQuery 缓存。

To get this working in following Javascript and in addition in CSS you have to set both.

要使其在以下 Javascript 和 CSS 中工作,您必须同时设置两者。

theaterA.find(".someLink").attr("data-itemname", "someValue");
theaterA.find(".someLink").data("itemname", "someValue");

回答by ThiefMaster

You must set the data using .data('itemname', 'someValue');. Using .attr()to set data attributes won't work: http://jsfiddle.net/ThiefMaster/YHsKx/

您必须使用 设置数据.data('itemname', 'someValue');。使用.attr()到的数据集的属性将无法正常工作:http://jsfiddle.net/ThiefMaster/YHsKx/

However, you canprovide inline values by using e.g. <div data-key="value">in the markup.

但是,您可以通过<div data-key="value">在标记中使用 eg提供内联值。

回答by mmmdearte

I can see that this has brought up some division on how to approach the data attribute setting.

我可以看到这对如何处理数据属性设置产生了一些分歧。

I too run into this problem and I found that the issue seemed to be simply the data attribute name formatting.

我也遇到了这个问题,我发现问题似乎只是数据属性名称格式

In my experience, you should avoid using hyphens in the data variable (the variable name that comes after "data-").

根据我的经验,您应该避免在数据变量(“ data-”之后的变量名称)中使用连字符。

This didn't work for me:

这对我不起作用:

[Markup]

[标记]

<div class="list" id="myElement1" data-item-order="some-value"> .... </div>

[jQuery]

[jQuery]

jQuery("#myElement1").data("item-order", "my-new-value");

But the following worked just fine! :) :

但以下工作得很好!:) :

(I use an underscore instead of a hyphen when required)

(我在需要时使用下划线而不是连字符)

[Markup]

[标记]

<div class="list" id="myElement1" data-item_order="some-value"> .... </div>

[jQuery]

[jQuery]

jQuery("#myElement1").data("item_order", "my-new-value");

I hope it helps. Cheers everyone!

我希望它有帮助。大家加油!