Mam następujące pole w widoku MVC:
@Html.TextBoxFor(model => model.Course.Title, new { data_helptext = "Old Text" })</span>
W oddzielnym pliku js chcę ustawić data-helptext
atrybut na wartość ciągu. Oto mój kod:
alert($(targetField).data("helptext"));
$(targetField).data("helptext", "Testing 123");
alert()
Wezwanie działa dobrze, to pokazuje tekst „stary tekst” w oknie alertu. Jednak wywołanie ustawienia data-helptext
atrybutu na „Testowanie 123” nie działa. „Stary tekst” jest nadal aktualną wartością atrybutu.
Czy używam wywołania data () nieprawidłowo? Sprawdziłem to w sieci i nie widzę, co robię źle.
Oto znaczniki HTML:
<input data-helptext="Old Text" id="Course_Title" name="Course.Title" type="text" value="" />
jquery
model-view-controller
attributes
custom-data-attribute
Jason Evans
źródło
źródło
data-
atrybutu HTML5 ?Odpowiedzi:
Jest o tym mowa w
.data()
dokumentacjiZostało to również omówione w artykule Dlaczego zmiany w jQuery $ .fn.data () nie aktualizują odpowiednich atrybutów html 5 data- *?
Demo mojej oryginalnej odpowiedzi poniżej nie wydaje się już działać.
Zaktualizowana odpowiedź
Znowu z
.data()
dokumentacjiTak więc,
<div data-role="page"></div>
co następuje$('div').data('role') === 'page'
Jestem całkiem pewien, że to
$('div').data('data-role')
działało w przeszłości, ale wydaje się, że już tak nie jest. Stworzyłem lepszą prezentację, która loguje się do HTML, zamiast otwierać konsolę i dodałem dodatkowy przykład konwersji wielu łączników do danych atrybutów camelCase .Zaktualizowane demo (25.07.2015)
Zobacz także 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();
Starsze demo
Oryginalna odpowiedź
W przypadku tego kodu HTML:
<div id="foo" data-helptext="bar"></div> <a href="#" id="changeData">change data value</a>
i ten JavaScript (z 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; });
Zobacz demo
Używając konsoli Chrome DevTools do inspekcji DOM, nie aktualizuje wartości, jak widać w konsoli, ale tak.
$('#foo').data('helptext', 'Testing 123');
$('#foo').attr('data-helptext', 'Testing 123');
źródło
data('key', 'value')
Metoda nie aktualizuje wartość w pamięci podręcznej jQuery, ale ze względu na wydajność (chyba mutację DOM) sam DOM nie jest aktualizowana..attr('key','value')
niezależnie od tego, czy to zrobiłeś,.data('key', 'value')
czy nie, prawda? Wydaje mi się to zbędne i mam problem z wyobrażeniem sobie scenariusza, w którym chciałbyś pisać do pamięci podręcznej DOM, ale nie do prawdziwego DOM. Może nie rozumiem cache jQuery; Czy zatem odwiedzający zobaczyłby wszystkie zmiany.data()
na ekranie, czy też nie?Miałem poważne problemy z
.data('property', value);
To nie było ustawianie
data-property
atrybutu.Zaczęto używać jQuery
.attr()
:.attr('property', value)
aby ustawić wartość i
.attr('property')
aby pobrać wartość.
Teraz to po prostu działa!
źródło
Zaakceptowana odpowiedź @ andyb zawiera mały błąd. W nawiązaniu do mojego komentarza do jego postu powyżej ...
W przypadku tego kodu HTML:
<div id="foo" data-helptext="bar"></div> <a href="#" id="changeData">change data value</a>
Musisz uzyskać dostęp do atrybutu w następujący sposób:
$('#foo').attr('data-helptext', 'Testing 123');
ale metoda danych taka:
$('#foo').data('helptext', 'Testing 123');
Powyższa poprawka dla metody .data () zapobiegnie „undefined”, a wartość danych zostanie zaktualizowana (podczas gdy HTML nie będzie)
Celem atrybutu „data” jest wiązanie (lub „łączenie”) wartości z elementem. Bardzo podobny do
onclick="alert('do_something')"
atrybutu, który wiąże akcję z elementem ... tekst jest bezużyteczny, po prostu chcesz, aby akcja zadziałała po kliknięciu elementu.Po powiązaniu danych lub czynności z elementem zwykle * nie ma potrzeby aktualizowania kodu HTML, a jedynie dane lub metodę, ponieważ tego właśnie użyłaby Twoja aplikacja (JavaScript). Jeśli chodzi o wydajność, nie rozumiem, dlaczego miałbyś chcieć również aktualizować HTML, nikt nie widzi atrybutu html (z wyjątkiem Firebuga lub innych konsol).
Jeden ze sposobów, w jaki możesz o tym pomyśleć: HTML (wraz z atrybutami) to tylko tekst. Dane, funkcje, obiekty itp. Używane przez JavaScript istnieją na osobnej płaszczyźnie. Tylko wtedy, gdy JavaScript zostanie poinstruowany, aby to zrobić, odczyta lub zaktualizuje tekst HTML, ale wszystkie dane i funkcje utworzone za pomocą JavaScript działają całkowicie niezależnie od tekstu / atrybutów HTML, które widzisz w konsoli Firebug (lub innej).
* Zwykle kładę nacisk na to, że jeśli masz przypadek, w którym musisz zachować i wyeksportować HTML (np. Jakiś rodzaj mikro-formatu / edytora tekstu obsługującego dane), gdzie HTML załaduje się świeżo na innej stronie, może potrzebujesz zaktualizować HTML też.
źródło
data
Wattr('data-helptext'
czyni różnicę, jeżeli odpowiedź zaakceptowane, a te z wielu głosów nie działają. +1Zdarzyło mi się to samo. Okazało się, że
var data = $("#myObject").data();
daje obiekt, którego nie można zapisać. Rozwiązałem to używając:
var data = $.extend({}, $("#myObject").data());
Od tamtej pory
data
był to standardowy, zapisywalny obiekt JS.źródło
$.extend...
możesz użyć,data
jak chcesz:,data.name = 'Nico'; data.questionSolved = true;
iconsole.log(data)
wyświetli te nowo dodane właściwościAby zacytować wycenę:
.data()
- Dokumentacja jQueryZauważ, że to (szczerze dziwne ) ograniczenie jest powstrzymywane tylko w przypadku używania
.data()
.Rozwiązanie? Użyj
.attr
zamiast tego.Oczywiście wielu z was może czuć się nieswojo, nie korzystając z dedykowanej metody. Rozważ następujący scenariusz:
Zdrowy rozsądek - dlaczego mieliby zmieniać już ustalony atrybut w ten sposób? Wyobraź sobie, że
class
zaczynasz przemianować się na grupę iid
na identyfikator . Internet się załamie.I nawet wtedy sam Javascript może to naprawić - I oczywiście, pomimo niesławnej niezgodności z HTML, REGEX (i wiele innych podobnych metod) może szybko zmienić nazwy atrybutów na ten nowy mityczny „standard”.
TL; DR
alert($(targetField).attr("data-helptext"));
źródło
Jak wspomniano,
.data()
metoda w rzeczywistości nie ustawi wartościdata-
atrybutu ani nie odczyta zaktualizowanych wartości, jeślidata-
atrybut się zmieni.Moim rozwiązaniem było rozszerzenie jQuery o
.realData()
metodę, która faktycznie odpowiada aktualnej wartości atrybutu:// 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);
UWAGA: Jasne, że możesz po prostu użyć
.attr()
, ale z mojego doświadczenia wynika, że większość programistów (aka ja) popełnia błąd, przeglądając.attr()
i.data()
jako wymienne, i często zastępuje jeden za drugim bez zastanowienia. Może to działać przez większość czasu, ale jest to świetny sposób na wprowadzenie błędów, szczególnie w przypadku wszelkiego rodzaju dynamicznych powiązań danych. Więc używając.realData()
, mogę bardziej szczegółowo opisać zamierzone zachowanie.źródło
Miałem ten sam problem. Ponieważ nadal możesz pobierać dane za pomocą metody .data (), musisz tylko znaleźć sposób zapisu do elementów. To jest metoda pomocnicza, której używam. Jak powiedziała większość ludzi, będziesz musiał użyć .attr. Mam zamianę dowolnego _ na - jak wiem, robi to. Nie znam żadnych innych postaci, które zastępuje ... jednak nie badałem tego.
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]); } }
EDYCJA: 01.05.2017
Okazało się, że nadal istnieją przypadki, w których nie można uzyskać poprawnych danych za pomocą wbudowanych metod, więc teraz używam:
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; };
źródło