我在MVC视图中有以下字段:
@Html.TextBoxFor(model => model.Course.Title, new { data_helptext = "Old Text" })</span>
在单独的js文件中,我想将data-helptext
属性设置为字符串值。这是我的代码:
alert($(targetField).data("helptext"));
$(targetField).data("helptext", "Testing 123");
alert()
调用正常,它在警告对话框中显示文本“旧文本”。但是,将data-helptext
属性设置为“测试123”的调用不起作用。 “旧文本”仍然是属性的当前值。
我是否错误地使用了对数据()的调用?我在网上看了这个,我看不出我做错了什么。
这是HTML标记:
<input data-helptext="Old Text" id="Course_Title" name="Course.Title" type="text" value="" />
答案 0 :(得分:239)
数据属性在第一次访问数据属性时被拉出,然后不再被访问或变异(然后所有数据值都内部存储在jQuery中)
Why don't changes to jQuery $.fn.data() update the corresponding html 5 data-* attributes?
也涵盖了这一点以下原始答案的演示似乎不再起作用。
更新回答
在jQuery 1.6中更改了嵌入破折号属性的处理,以符合W3C HTML5规范。
因此,对于<div data-role="page"></div>
,以下情况属实$('div').data('role') === 'page'
我很确定$('div').data('data-role')
过去有效,但现在情况似乎不再如此。我已经创建了一个更好的展示,它可以记录到HTML而不必打开控制台,并为camelCase data- attributes转换添加了多连字符的其他示例。
<强> 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');
不会更新控制台<中显示的值/ em>但$('#foo').attr('data-helptext', 'Testing 123');
确实如此。
答案 1 :(得分:34)
我遇到了严重的问题
.data('property', value);
没有设置data-property
属性。
开始使用jQuery的.attr()
:
获取集合中第一个元素的属性值 匹配的元素或为每个匹配的元素设置一个或多个属性 元件。
.attr('property', value)
设置值和
.attr('property')
检索值。
现在它正常运作!
答案 2 :(得分:8)
@ andyb接受的答案有一个小错误。继我对上述帖子的评论......
对于这个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()方法的上述修复将阻止&#34; undefined&#34;并且数据值将被更新(而HTML不会)
&#34;数据的重点&#34; attribute是绑定(或&#34; link&#34;)一个值与元素。非常类似于onclick="alert('do_something')"
属性,它将一个动作绑定到元素......文本没用,你只想让动作在单击元素时起作用。
一旦数据或操作绑定到元素,通常* 就不需要更新HTML,只需更新数据或方法,因为这是您的应用程序(JavaScript)将使用的。性能方面,我不明白为什么你还想要更新HTML,没有人看到html属性(Firebug或其他控制台除外)。
您可能想要考虑的一种方式: HTML(以及属性)只是文本。 JavaScript使用的数据,函数,对象等存在于单独的平面上。只有在指示JavaScript这样做时,它才会读取或更新HTML文本,但您使用JavaScript创建的所有数据和功能都与您在Firebug(或其他)控制台中看到的HTML文本/属性完全分开。 / p>
*我强调通常是,因为如果你有一个需要保存和导出HTML的例子(例如某种微格式/数据识别文本编辑器),HTML将在其中加载新的另一页,那么也许你需要更新HTML。
答案 3 :(得分:6)
发生在我身上。事实证明
var data = $("#myObject").data();
给你一个不可写的对象。我用以下方法解决了它:
var data = $.extend({}, $("#myObject").data());
从那以后,data
是一个标准的,可写的JS对象。
答案 4 :(得分:3)
引用引用:
数据属性第一次被拉入数据属性 访问,然后不再访问或变异(所有数据值 然后在内部存储在jQuery中。
.data()
- jQuery Documentiation
请注意,这个(坦率地奇数)限制仅限于使用.data()
。
解决方案?请改用.attr
。
当然,你们中的一些人可能会因为不使用它的专用方法而感到不舒服。请考虑以下情形:
常识 - 为什么他们会更改已经建立的属性?试想一下class
开始重命名为组,id
重命名为标识符。互联网会破裂。
即便如此,Javascript本身也有能力解决这个问题 - 当然,尽管它与HTML有着臭名昭着的不兼容性,但REGEX(以及各种类似方法)可以快速将您的属性重命名为这个新的神话“标准”。
TL; DR
alert($(targetField).attr("data-helptext"));
答案 5 :(得分:1)
如上所述,.data()
方法实际上不会设置data-
属性的值,如果data-
属性发生更改,它也不会读取更新的值。
我的解决方案是使用 .realData()
方法扩展jQuery,该方法实际上对应于属性的当前值:
// Alternative to .data() that updates data- attributes, and reads their current value.
(function($){
$.fn.realData = function(name,value) {
if (value === undefined) {
return $(this).attr('data-'+name);
} else {
$(this).attr('data-'+name,value);
}
};
})(jQuery);
注意:当然,您可以只使用.attr()
,但是根据我的经验,大多数开发人员(也就是我)都犯了查看.attr()
和.data()
的错误。可以互换,并且经常在不考虑的情况下将一个替换为另一个。它可能在大多数时间都有效,但它是引入错误的好方法,尤其是在处理任何类型的动态数据绑定时。因此,通过使用.realData()
,我可以更明确地了解预期的行为。
答案 6 :(得分:0)
有同样的问题。由于您仍然可以使用.data()方法获取数据,因此您只需要找到一种写入元素的方法。这是我使用的辅助方法。像大多数人所说的那样,你将不得不使用.attr。我用它代替任何_用 - 就像我知道的那样。我不知道它取代了任何其他角色......但我还没有研究过。
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]);
}
}
编辑:5/1/2017
我发现仍然存在使用内置方法无法获取正确数据的情况,因此我现在使用的内容如下:
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;
};