Pardonnez-moi de ne pas être plus précis à ce sujet. J'ai un bug tellement étrange. Après le chargement de la documentation, je boucle certains éléments qui ont à l'origine data-itemname=""
et je définis ces valeurs à l'aide de .attr("data-itemname", "someValue")
.
Problème: plus tard, lorsque je boucle sur ces éléments, si je le fais elem.data().itemname
, j'obtiens ""
, mais si je le fais elem.attr("data-itemname")
, j'obtiens "someValue"
. C'est comme si le .data()
getter de jQuery n'obtient que les éléments qui sont initialement définis pour contenir une valeur, mais s'ils sont initialement vides, puis définis ultérieurement, ils .data()
n'obtiennent pas la valeur plus tard.
J'ai essayé de recréer ce bogue mais je n'ai pas pu.
Éditer
J'ai recréé le bogue! http://jsbin.com/ihuhep/edit#javascript,html,live
Aussi, extraits du lien ci-dessus ...
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")
paselem.data().itemname
?elem.data().itemname = somevalue;
ne change donc pas les données sous-jacentes.)Réponses:
J'ai rencontré un "bug" similaire il y a quelques jours en travaillant avec
.data()
et.attr('data-name')
pour les attributs de données HTML5.Le comportement que vous décrivez n'est pas un bogue, mais est intentionnel.
L'
.data()
appel est spécial - non seulement il récupère les attributs de données HTML5, mais il tente également d'évaluer / analyser les attributs. Donc, avec un attribut commedata-myjson='{"hello":"world"}'
lors de la récupération via.data()
retournera unObject
while la récupération via.attr()
retournera une chaîne. Voir l'exemple jsfiddle.Comme
.data()
un traitement supplémentaire, jQuery stocke les résultats de l'évaluation des attributs dans$.cache
- après tout, une fois qu'un attribut de données a été évalué, il serait inutile de le réévaluer à chaque.data()
appel - d'autant plus que les variables de données peuvent contenir des chaînes JSON complexes.J'ai dit tout cela pour dire ce qui suit: après avoir récupéré un attribut via
.data()
les modifications apportées par.attr('data-myvar', '')
ne sera pas vu par les.data()
appels suivants . Testez ceci sur jsfiddle.Pour éviter ce problème , ne mélangez pas
.data
et n'appelez pas.attr()
. Utilise l'un ou l'autre.la source
Ceci est le résultat d'un malentendu:
data
n'est PAS un accesseur pour lesdata-*
attributs . C'est à la fois plus et moins que cela.data
est un accesseur pour le cache de données de jQuery sur l'élément. Ce cache est initialisé à partir desdata-*
attributs s'il y en a, mais n'écritdata
jamais dans les attributs, et la modification de l'attribut ne change pas le cache de données après l'initialisation:data
masse également ce qu'il trouve de différentes manières, en devinant les types de données, en créantdata("answer")
un élément avecdata-answer="42"
un nombre, pas une chaîne, ou même en analysant les choses en JSON si elles ressemblent à JSON:Si vous souhaitez utiliser les attributs (à la fois les lire et les définir), utilisez
attr
, pasdata
.attr
est un accesseur pour les attributs.la source
C'est parce que le nom de l'attribut est
data-itemname
. Vous ne pouvez pas utiliser-
dans laobj.attribute
notation abrégée (obj.data-itemname serait interprété comme "obj.data moins itemname").la source
.attr("data-itemname", "someValue")
modifie le DOM..data("itemname", "someValue")
modifie le cache jQuery.Pour que cela fonctionne en suivant Javascript et en plus en CSS, vous devez définir les deux.
la source
Pourquoi n'utilisez-vous pas
.data()
partout?Vous pouvez également déclarer les valeurs par défaut en ligne sur le HTML, ce qui convient également.
et
si tu veux le changer tu fais juste
et pour le supprimer complètement, vous pouvez invoquer
vous devriez vraiment essayer d'éviter d'utiliser
.attr("data-*")
, je ne sais pas pourquoi vous voudriez le faire de toute façon.la source
.attr('data-*', ...)
ne rendra pas les données visibles pour.data()
getAttribute()
etsetAttribute()
- les deux méthodes accéderont aux attributs réels et cela fonctionnera à nouveau. Ou vous utiliseriez simplement ladataSet
propriété fournie par les navigateurs modernes.class
plutôt un car les navigateurs ont des fonctions natives pour obtenir des éléments avec une certaine classe.Vous devez définir les données à l'aide de
.data('itemname', 'someValue');
. L'utilisation.attr()
pour définir les attributs de données ne fonctionnera pas: http://jsfiddle.net/ThiefMaster/YHsKx/Cependant, vous pouvez fournir des valeurs en ligne en utilisant par exemple
<div data-key="value">
dans le balisage.la source
.data()
appel définit l'attribut, tandis que l'.attr()
appel ne fait rien..attr()
du tout, seulement.data()
, et, la longueur du sélecteur$(".someLink[data-tofilllater='theater5link']")
, est égale à zéro. donc c'est comme si je devais utiliser.attr()
: /Je peux voir que cela a soulevé une certaine division sur la façon d'aborder le paramètre d'attribut de données.
Moi aussi, je rencontre ce problème et j'ai trouvé que le problème semblait être simplement le formatage du nom d'attribut de données .
D'après mon expérience, vous devriez éviter d'utiliser des traits d'union dans la variable data (le nom de la variable qui vient après " data- ").
Cela n'a pas fonctionné pour moi:
[Balisage]
[jQuery]
Mais ce qui suit a très bien fonctionné! :):
(J'utilise un trait de soulignement au lieu d'un trait d'union si nécessaire)
[Balisage]
[jQuery]
J'espère que cela aide. Salut tout le monde!
la source