Wybaczcie, że nie jestem bardziej szczegółowy w tej sprawie. Mam taki dziwny błąd. Po załadowaniu dokumentu zapętlam niektóre elementy, które pierwotnie miały data-itemname=""
, i ustawiam te wartości za pomocą .attr("data-itemname", "someValue")
.
Problem: Kiedy później zapętlę te elementy, jeśli tak elem.data().itemname
, otrzymam ""
, ale jeśli tak elem.attr("data-itemname")
, otrzymam "someValue"
. To tak, jakby .data()
getter jQuery pobierał tylko te elementy, które są początkowo ustawione tak, aby zawierały jakąś wartość, ale jeśli są pierwotnie puste, a później ustawione, później .data()
nie pobiera wartości.
Próbowałem odtworzyć ten błąd, ale nie udało mi się.
Edytować
Odtworzyłem błąd! http://jsbin.com/ihuhep/edit#javascript,html,live
Ponadto fragmenty z powyższego linku ...
JS:
var theaters = [
{ name: "theater A", theaterId: 5 },
{ name: "theater B", theaterId: 17 }
];
$("#theaters").html(
$("#theaterTmpl").render(theaters)
);
// DOES NOT WORK - .data("name", "val") does NOT set the val
var theaterA = $("[data-theaterid='5']");
theaterA.find(".someLink").data("tofilllater", "theater5link"); // this does NOT set data-tofilllater
$(".someLink[data-tofilllater='theater5link']").html("changed link text"); // never gets changed
// WORKS - .attr("data-name", "val") DOES set val
var theaterB = $("[data-theaterid='17']");
theaterB.find(".someLink").attr("data-tofilllater", "theater17link"); // this does set data-tofilllater
$(".someLink[data-tofilllater='theater17link']").html("changed link text");
HTML:
<body>
<div id="theaters"></div>
</body>
<script id="theaterTmpl" type="text/x-jquery-tmpl">
<div class="theater" data-theaterid="{{=theaterId}}">
<h2>{{=name}}</h2>
<a href="#" class="someLink" data-tofilllater="">need to change this text</a>
</div>
</script>
elem.data("itemname")
nieelem.data().itemname
?elem.data().itemname = somevalue;
sposób nie zmienia podstawowych danych.)Odpowiedzi:
Kilka dni temu napotkałem podobny „błąd” podczas pracy z atrybutami danych HTML5
.data()
i.attr('data-name')
dla nich.Zachowanie, które opisujesz, nie jest błędem, ale zostało zaprojektowane.
.data()
Wezwanie jest wyjątkowy - to nie tylko pobierać dane atrybutów HTML5 to także próba oceny / analizowania atrybuty. Tak więc z atrybutem takim jakdata-myjson='{"hello":"world"}'
przy pobieraniu przez.data()
zwróciObject
while pobieranie przez.attr()
zwróci ciąg. Zobacz przykład jsfiddle.Ponieważ
.data()
wymaga dodatkowego przetwarzania, jQuery przechowuje wyniki oceny atrybutów w$.cache
- w końcu po ocenie atrybutu danych byłoby marnotrawstwem ponowne oszacowanie przy każdym.data()
wywołaniu - zwłaszcza, że zmienne danych mogą zawierać złożone ciągi JSON.Powiedziałem to wszystko, aby powiedzieć, co następuje: po pobraniu atrybutu za pośrednictwem
.data()
jakichkolwiek zmian dokonanych przez.attr('data-myvar', '')
nie będzie widoczny dla kolejnych.data()
wywołań. Przetestuj to na jsfiddle.Aby uniknąć tego problemu , nie mieszaj
.data
i nie.attr()
dzwoni. Użyj jednego lub drugiego.źródło
Jest to wynikiem nieporozumienia:
data
NIE jest akcesorium dodata-*
atrybutów . To zarówno więcej, jak i mniej.data
jest akcesorem dla pamięci podręcznej danych jQuery w elemencie. Ta pamięć podręczna jest inicjowana zdata-*
atrybutów, jeśli istnieją, aledata
nigdy nie zapisuje do atrybutów, ani zmiana atrybutu nie zmienia pamięci podręcznej danych po inicjalizacji:data
masuje również to, co znajdzie na różne sposoby, zgadując typy danych, tworzącdata("answer")
element zdata-answer="42"
liczbą, a nie ciągiem, a nawet analizując rzeczy jako JSON, jeśli wyglądają jak JSON:Jeśli chcesz używać atrybutów (zarówno do czytania, jak i ustawiania), użyj
attr
, niedata
.attr
jest akcesorium do atrybutów.źródło
To dlatego, że nazwa atrybutu to
data-itemname
. Nie można używać-
wobj.attribute
notacji skróconej (obj.data-itemname byłoby interpretowane jako „obj.data minus itemname”).źródło
.attr("data-itemname", "someValue")
modyfikuje DOM..data("itemname", "someValue")
modyfikuje pamięć podręczną jQuery.Aby to działało w Javascript i dodatkowo w CSS, musisz ustawić oba.
źródło
Dlaczego nie używasz
.data()
wszędzie?Możesz także zadeklarować domyślne wartości w kodzie HTML, co też jest w porządku.
i
jeśli chcesz to zmienić, po prostu to robisz
i aby go całkowicie usunąć, możesz przywołać
naprawdę powinieneś próbować i unikać używania
.attr("data-*")
, i tak nie wiem, dlaczego chcesz to zrobić.źródło
.attr('data-*', ...)
nie spowoduje, że dane będą widoczne dla.data()
getAttribute()
isetAttribute()
- więc obie metody będą dostęp do rzeczywistych atrybutów i będą działać ponownie. Lub po prostu skorzystaj zdataSet
właściwości udostępnianej przez nowoczesne przeglądarki.class
zamiast tego, ponieważ przeglądarki mają natywne funkcje do pobierania elementów z określoną klasą.Musisz ustawić dane za pomocą
.data('itemname', 'someValue');
. Używanie.attr()
do ustawiania atrybutów danych nie zadziała: http://jsfiddle.net/ThiefMaster/YHsKx/Możesz jednak podać wartości wbudowane, używając np.
<div data-key="value">
W znacznikach.źródło
.data()
wezwanie ustawia atrybut, natomiast.attr()
rozmowa nic nie robi..attr()
, tylko.data()
, a długość selektora$(".someLink[data-tofilllater='theater5link']")
wynosi zero. więc to tak, jakbym musiał użyć.attr()
: /Widzę, że spowodowało to podział na sposób podejścia do ustawiania atrybutów danych.
Ja również napotkałem ten problem i stwierdziłem, że wydaje się, że jest to po prostu formatowanie nazwy atrybutu danych .
Z mojego doświadczenia wynika, że należy unikać używania łączników w zmiennej danych (nazwa zmiennej występująca po „ dane- ”).
To nie zadziałało dla mnie:
[Narzut]
[jQuery]
Ale poniższe działały dobrze! :):
(W razie potrzeby używam podkreślenia zamiast łącznika)
[Narzut]
[jQuery]
Mam nadzieję, że to pomoże. Pozdrawiam wszystkich!
źródło