无法使用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; };