jQuery .data() 不起作用,但 .attr() 起作用 [英] jQuery .data() does not work, but .attr() does

查看:40
本文介绍了jQuery .data() 不起作用,但 .attr() 起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请原谅我没有对此进行更具体的说明.我有一个如此奇怪的错误.文档加载后,我循环了一些最初具有 data-itemname="" 的元素,并使用 .attr("data-itemname", "someValue") 设置这些值代码>.

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

我一直在尝试重现这个错误,但没有成功.

编辑

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

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

JS:

var 剧院 = [{名称:剧院A",剧院ID:5},{名称:剧院B",剧院ID:17}];$("#theaters").html($("#theaterTmpl").render(剧院));//不起作用 - .data("name", "val") 不设置 valvar theatreA = $("[data-theaterid='5']");TheaterA.find(".someLink").data("tofilllater", "theater5link");//这不会设置 data-tofilllater$(".someLink[data-tofilllater='theater5link']").html("更改链接文本");//永远不会改变//WORKS - .attr("data-name", "val") 确实设置了 valvar theatreB = $("[data-theaterid='17']");TheaterB.find(".someLink").attr("data-tofilllater", "theater17link");//这确实设置了 data-tofilllater$(".someLink[data-tofilllater='theater17link']").html("更改链接文本");

HTML:

<div id="剧院"></div><script id="theaterTmpl" type="text/x-jquery-tmpl"><div class="theater" data-theaterid="{{=theaterId}}"><h2>{{=name}}</h2><a href="#" class="someLink" data-tofilllater="">需要更改此文本</a>

解决方案

几天前我在使用 .data().attr('data-name') 用于 HTML5 数据属性.

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

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

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

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

为了避免这个问题不要混合使用 .data.attr() 调用.使用一个或另一个.

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").

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.

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

Also, snippets from above link...

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:

<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>

解决方案

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

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 Object while retrieval via .attr() will return a string. See jsfiddle example.

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.

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.

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

这篇关于jQuery .data() 不起作用,但 .attr() 起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆