Невозможно установить атрибут данных с помощью jQuery Data() API
У меня есть следующее поле в представлении 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="" />
Ответы
Ответ 1
Он упоминается в .data()
документации
Атрибуты данных вытаскиваются при первом доступе к свойствам данных, а затем больше не доступны или не изменяются (все значения данных затем сохраняются внутри jQuery)
Об этом также говорилось в Почему изменения в jQuery $.fn.data() не обновляют соответствующие атрибуты html 5 data- *?
Демо на моем первоначальном ответе ниже, похоже, больше не работает.
Обновленный ответ
Опять же, из .data()
documentation
Обработка атрибутов встроенными тире была изменена в jQuery 1.6, чтобы соответствовать спецификации W3C HTML5.
Итак, для <div data-role="page"></div>
верно следующее: $('div').data('role') === 'page'
Я уверен, что $('div').data('data-role')
работал в прошлом, но, похоже, это не так. Я создал лучшую витрину, которая регистрируется в HTML, вместо того, чтобы открывать Консоль и добавила дополнительный пример атрибута multi-hyphen to camelCase data-attributes.
Обновлено демо (2015-07-25)
Также см. jQuery Data vs 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');
делает.
Ответ 2
У меня были серьезные проблемы с
.data('property', value);
Он не устанавливал атрибут data-property
.
Начнется использование jQuery .attr()
:
Получить значение атрибута для первого элемента в наборе согласованные элементы или задать один или несколько атрибутов для каждого совпадающего элемент.
.attr('property', value)
чтобы установить значение и
.attr('property')
чтобы получить значение.
Теперь это просто работает!
Ответ 3
Принятый ответ @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() предотвратит "undefined", и значение данных будет обновлено (пока HTML не будет)
Точкой атрибута "data" является привязка (или "ссылка" ) значения к элементу. Очень похоже на атрибут onclick="alert('do_something')"
, который связывает действие с элементом... текст бесполезен, вы просто хотите, чтобы действие работало, когда они нажимают на элемент.
Как только данные или действие привязаны к элементу, обычно нет необходимости обновлять HTML, только данные или метод, так как это будет использоваться вашим приложением (JavaScript). Производительность мудрая, я не понимаю, почему вы хотите также обновить HTML в любом случае, никто не видит атрибут html (кроме Firebug или других консолей).
Один из способов, который вы могли бы подумать об этом:
HTML (наряду с атрибутами) - это просто текст. Данные, функции, объекты и т.д., Которые используются JavaScript, существуют на отдельной плоскости. Только тогда, когда JavaScript будет проинструктирован об этом, он будет читать или обновлять текст HTML, но все данные и функции, которые вы создаете с помощью JavaScript, действуют полностью отдельно от HTML-текста/атрибутов, которые вы видите в своей Firebug (или другой) консоли.
* Я обычно делаю акцент, потому что, если у вас есть случай, когда вам нужно сохранить и экспортировать HTML (например, какой-то текстовый редактор с микроформатом/данными), где HTML будет загружаться на другой странице, тогда, возможно, вам понадобится HTML также обновлен.
Ответ 4
Случилось то же самое со мной. Оказывается, что
var data = $("#myObject").data();
предоставляет объект, не подлежащий записи. Я решил это, используя:
var data = $.extend({}, $("#myObject").data());
И с этого момента data
был стандартным, записываемым JS-объектом.
Ответ 5
Чтобы процитировать цитату:
Атрибуты данных вытягиваются в первый раз, когда свойство данных доступ к ним и затем больше не доступны или не изменяются (все значения данных затем сохраняются внутри jQuery).
.data()
- Документация jQuery
Обратите внимание, что это (нечетное) ограничение ограничивается только использованием .data()
.
Решение? Вместо этого используйте .attr
.
Конечно, некоторые из вас могут чувствовать себя некомфортно, если не использовать выделенный метод. Рассмотрим следующий сценарий:
- "Стандарт" обновляется, так что часть пользовательских атрибутов больше не требуется/заменяется
Здравый смысл - зачем им менять уже установленный атрибут? Представьте себе, что class
начинает переименовываться в группу и id
в идентификатор. Интернет сломается.
И даже тогда сам Javascript имеет возможность исправить это. И, конечно же, несмотря на это, позорная несовместимость с HTML, REGEX (и множество подобных методов) может быстро переименовать ваши атрибуты в этот новый мифический "стандарт".
TL; DR
alert($(targetField).attr("data-helptext"));
Ответ 6
Была та же проблема. Поскольку вы все еще можете получать данные с использованием метода .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;
};