首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >jQuery .data()不起作用,但.attr()起作用

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

Stack Overflow用户
提问于 2012-01-03 02:14:34
回答 7查看 94.9K关注 0票数 127

请原谅我没有在这件事上说得更具体。我有一只奇怪的虫子。在文档加载之后,我循环一些最初具有data-itemname=""的元素,并使用.attr("data-itemname", "someValue")设置这些值。

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

我一直试图重新创建这个bug,但一直未能。

编辑

我重新创建了这个bug!http://jsbin.com/ihuhep/edit#javascript,html,live

还有上面链接上的片段..。

联署材料:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
<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>
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-01-03 05:34:58

几天前,在使用.data().attr('data-name')处理HTML5数据属性时,我遇到了一个类似的"bug“。

您所描述的行为并不是一个bug,而是由设计造成的。

.data()调用是特殊的-它不仅检索HTML5数据属性,还试图计算/解析属性。因此,对于像data-myjson='{"hello":"world"}'这样的属性,当通过.data()检索时,将返回一个Object,而通过.attr()检索将返回一个字符串。参见jsfiddle示例。

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

我这么说是为了说明如下:在通过.data() 检索属性之后, .attr('data-myvar', '') 所做的任何更改都不会被随后的 .data() 调用所看到。

为了避免这个问题,不要将.data.attr()调用混合在一起。用一个或另一个。

票数 238
EN

Stack Overflow用户

发布于 2017-07-17 16:26:16

这是误解的结果:数据 不是属性的访问器。不止是这样。

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

代码语言:javascript
运行
复制
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"));
代码语言:javascript
运行
复制
<div data-example="initial value"></div>

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

data还以各种方式传递它所发现的内容,猜测数据类型,在一个元素上使data-answer="42"上的data("answer")成为一个数字,而不是一个字符串,甚至将事物解析为JSON,如果它们看起来像JSON:

代码语言:javascript
运行
复制
console.log(typeof $("[data-answer]").data("answer"));
console.log(typeof $("[data-json]").data("json"));
console.log(typeof $("[data-str]").data("str"));
代码语言:javascript
运行
复制
<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>

如果您想使用属性(同时读取和设置属性),请使用attr,而不是dataattr 是属性的访问器

票数 25
EN

Stack Overflow用户

发布于 2018-07-23 14:13:11

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

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

要使它在后面的Javascript中工作,另外在CSS中,您必须同时设置这两种方式。

代码语言:javascript
运行
复制
theaterA.find(".someLink").attr("data-itemname", "someValue");
theaterA.find(".someLink").data("itemname", "someValue");
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8707226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档