无法使用jQuery Data()API设置数据属性

我在MVC视图中获得了以下字段:

@Html.TextBoxFor(model => model.Course.Title, new { data_helptext = "Old Text" })</span> 

在一个单独的js文件中,我想将data-helptext属性设置为一个string值。 这是我的代码:

 alert($(targetField).data("helptext")); $(targetField).data("helptext", "Testing 123"); 

alert()调用工作正常,它显示警报对话框中的文本“旧文本”。 但是,将data-helptext属性设置为“Testing 123”的调用不起作用。 “旧文本”仍然是属性的当前值。

我是否正确使用data()的调用? 我在网上看了这个,我看不出我做错了什么。

这是HTML标记:

 <input data-helptext="Old Text" id="Course_Title" name="Course.Title" type="text" value="" /> 

它在.data()文档中提到

数据属性在第一次访问数据属性时被取出,然后不再被访问或变异(所有的数据值都被存储在jQuery中)

这也包括了为什么不改变jQuery $ .fn.data()更新相应的html5 data- *属性?

在我原来的答案下面的演示似乎不再工作。

更新了答案

再次,从.data()文档

在jQuery 1.6中修改了embedded破折号属性的处理方式,以符合W3C HTML5规范。

所以对于<div data-role="page"></div> ,以下是真的$('div').data('role') === 'page'

我相当肯定$('div').data('data-role')在过去的工作,但似乎不再是这种情况。 我创build了一个更好的展示,它将logging到HTML,而不必打开控制台,并为驼峰数据属性转换添加了多连字符的附加示例。

更新演示(2015-07-25)

另请参阅jQuery数据与Attr?

HTML

 <div id="changeMe" data-key="luke" data-another-key="vader"></div> <a href="#" id="changeData"></a> <table id="log"> <tr><th>Setter</th><th>Getter</th><th>Result of calling getter</th><th>Notes</th></tr> </table> 

JavaScript (jQuery 1.6.2+)

 var $changeMe = $('#changeMe'); var $log = $('#log'); var logger; (logger = function(setter, getter, note) { note = note || ''; eval('$changeMe' + setter); var result = eval('$changeMe' + getter); $log.append('<tr><td><code>' + setter + '</code></td><td><code>' + getter + '</code></td><td>' + result + '</td><td>' + note + '</td></tr>'); })('', ".data('key')", "Initial value"); $('#changeData').click(function() { // set data-key to new value logger(".data('key', 'leia')", ".data('key')", "expect leia on jQuery node object but DOM stays as luke"); // try and set data-key via .attr and get via some methods logger(".attr('data-key', 'yoda')", ".data('key')", "expect leia (still) on jQuery object but DOM now yoda"); logger("", ".attr('key')", "expect undefined (no attr <code>key</code>)"); logger("", ".attr('data-key')", "expect yoda in DOM and on jQuery object"); // bonus points logger('', ".data('data-key')", "expect undefined (cannot get via this method)"); logger(".data('anotherKey')", ".data('anotherKey')", "jQuery 1.6+ get multi hyphen <code>data-another-key</code>"); logger(".data('another-key')", ".data('another-key')", "jQuery < 1.6 get multi hyphen <code>data-another-key</code> (also supported in jQuery 1.6+)"); return false; }); $('#changeData').click(); 

较旧的演示


原始答案

对于这个HTML:

 <div id="foo" data-helptext="bar"></div> <a href="#" id="changeData">change data value</a> 

和这个JavaScript(使用jQuery 1.6.2)

 console.log($('#foo').data('helptext')); $('#changeData').click(function() { $('#foo').data('helptext', 'Testing 123'); // $('#foo').attr('data-helptext', 'Testing 123'); console.log($('#foo').data('data-helptext')); return false; }); 

看演示

使用Chrome DevTools 控制台检查DOM, $('#foo').data('helptext', 'Testing 123'); 不会更新控制台中的值,而是$('#foo').attr('data-helptext', 'Testing 123'); 确实。

我遇到了严重的问题

 .data('property', value); 

这不是设置data-property属性。

开始使用jQuery的.attr()

获取匹配元素集中第一个元素的属性值,或为每个匹配元素设置一个或多个属性。

 .attr('property', value) 

设置值和

 .attr('property') 

检索值。

现在它只是工作!

@andyb接受的答案有一个小错误。 继我上面对他的post发表评论之后,

对于这个HTML:

 <div id="foo" data-helptext="bar"></div> <a href="#" id="changeData">change data value</a> 

你需要像这样访问属性:

 $('#foo').attr('data-helptext', 'Testing 123'); 

但数据方法是这样的:

 $('#foo').data('helptext', 'Testing 123'); 

上面的.data()方法的修复将防止“未定义”,数据值将被更新(而HTML不会)

“data”属性的要点是将一个值与元素绑定(或“链接”)。 非常类似于onclick="alert('do_something')"属性,它将一个动作绑定到元素上……文本没用,你只需要单击元素时动作就可以工作。

一旦数据或动作绑定到元素, 通常*不需要更新HTML,只有数据或方法,因为这是您的应用程序(JavaScript)将使用。 性能方面,我不明白你为什么也想更新HTML,没有人看到HTML属性(Firebug或其他控制台除外)。

您可能想要考虑的一种方法:HTML(与属性一起)只是文本。 JavaScript使用的数据,函数,对象等存在于一个单独的平面上。 只有当JavaScript被指示这样做时,它才会读取或更新HTML文本,但是您使用JavaScript创build的所有数据和function都完全独立于您在Firebug(或其他)控制台中看到的HTML文本/属性。

*我强调通常是因为如果你有一个情况,你需要保存和导出的HTML(例如某种微格式/数据感知文本编辑器)的HTML将加载在另一个页面上新鲜,那么也许你需要更新的HTML太。

对我也发生了同样的情况。 事实certificate

 var data = $("#myObject").data(); 

给你一个不可写的对象。 我解决了它使用:

 var data = $.extend({}, $("#myObject").data()); 

从那以后, data是一个标准的,可写的JS对象。

引用一个报价:

数据属性在访问数据属性的第一次被拉出,然后不再被访问或变异(所有的数据值然后被内部存储在jQuery中)。

.data() – jQuery Documentiation

请注意,这个( 奇怪的 )限制只能用于.data()

解决scheme? 改用.attr

当然,有些人可能会觉得不习惯使用专门的方法。 考虑以下情况:

  • “标准”已更新,以便自定义属性的数据部分不再需要/被replace

常识 – 为什么他们会改变一个已经build立的属性呢? 试想一下, class开始重新命名为标识符 。 互联网将打破。

即使如此,Javascript本身也有能力解决这个问题 – 当然,尽pipe它与HTML不兼容,REGEX(以及各种类似的方法)可以迅速将属性重命名为这个新的“神话”标准。

TL; DR

 alert($(targetField).attr("data-helptext")); 

有同样的问题。 由于您仍然可以使用.data()方法获取数据,因此只需要找出写入元素的方法即可。 这是我使用的帮手方法。 像大多数人所说的,你将不得不使用.attr。 我用它取代了任何_,正如我所知道的那样。 我没有意识到任何其他angular色,但我没有研究过。

 function ExtendElementData(element, object){ //element is what you want to set data on //object is a hash/js-object var keys = Object.keys(object); for (var i = 0; i < keys.length; i++){ var key = keys[i]; $(element).attr('data-'+key.replace("_", "-"), object[key]); } } 

编辑:2017/5/1

我发现还有一些情况下,你不能使用内置的方法得到正确的数据,所以我现在使用的是如下:

 function setDomData(element, object){ //object is a hash var keys = Object.keys(object); for (var i = 0; i < keys.length; i++){ var key = keys[i]; $(element).attr('data-'+key.replace("_", "-"), object[key]); } }; function getDomData(element, key){ var domObject = $(element).get(0); var attKeys = Object.keys(domObject.attributes); var values = null; if (key != null){ values = $(element).attr('data-' + key); } else { values = {}; var keys = []; for (var i = 0; i < attKeys.length; i++) { keys.push(domObject.attributes[attKeys[i]]); } for (var i = 0; i < keys.length; i++){ if(!keys[i].match(/data-.*/)){ values[keys[i]] = $(element).attr(keys[i]); } } } return values; }; 
Interesting Posts