Question jQuery Data vs Attr?


Quelle est la différence d'utilisation entre $.data et $.attr en utilisant data-someAttribute?

Ma compréhension est que $.data est stocké dans jQuery $.cache, pas le DOM. Par conséquent, si je veux utiliser $.cache pour le stockage de données, je devrais utiliser $.data. Si je veux ajouter des attributs de données HTML5, je devrais utiliser $.attr("data-attribute", "myCoolValue").


463
2017-08-31 18:26


origine


Réponses:


Si vous transmettez des données à un élément DOM du serveur, vous devez définir les données sur l'élément:

<a id="foo" data-foo="bar" href="#">foo!</a>

Les données peuvent ensuite être consultées en utilisant .data() en jQuery:

console.log( $('#foo').data('foo') );
//outputs "bar"

Cependant, lorsque vous stockez des données sur un noeud DOM dans jQuery en utilisant les données, les variables sont stockées sur le noeud objet. Ceci est pour accueillir des objets complexes et des références comme le stockage des données sur le noeud élément en tant qu'attribut, seules les valeurs de chaîne seront prises en compte.

Poursuivant mon exemple d'en haut:
$('#foo').data('foo', 'baz');

console.log( $('#foo').attr('data-foo') );
//outputs "bar" as the attribute was never changed

console.log( $('#foo').data('foo') );
//outputs "baz" as the value has been updated on the object

En outre, la convention de dénomination des attributs de données a un peu de "gotcha" caché:

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('fooBarBaz') );
//outputs "fizz-buzz" as hyphens are automatically camelCase'd

La clé coupée fonctionnera toujours:

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('foo-bar-baz') );
//still outputs "fizz-buzz"

Cependant l'objet renvoyé par .data() n'aura pas la clé définie par un trait d'union:

$('#bar').data().fooBarBaz; //works
$('#bar').data()['fooBarBaz']; //works
$('#bar').data()['foo-bar-baz']; //does not work

C'est pour cette raison que je suggère d'éviter la clé de césure en javascript.

Pour le HTML, continuez à utiliser le formulaire avec trait d'union. Les attributs HTML sont censés être automatiquement mis en minuscules ASCII, alors <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>, et <dIv DaTa-FoObAr></DiV> sont supposé être considéré comme identique, mais pour la meilleure compatibilité, la forme minuscule doit être préférée.

le .data() méthode effectuera également une fonction de base automatique si la valeur correspond à un modèle reconnu:

HTML:
<a id="foo"
    href="#"
    data-str="bar"
    data-bool="true"
    data-num="15"
    data-json='{"fizz":["buzz"]}'>foo!</a>
JS:
$('#foo').data('str');  //`"bar"`
$('#foo').data('bool'); //`true`
$('#foo').data('num');  //`15`
$('#foo').data('json'); //`{fizz:['buzz']}`

Cette capacité de moulage automatique est très pratique pour instancier des widgets et des plugins:

$('.widget').each(function () {
    $(this).widget($(this).data());
    //-or-
    $(this).widget($(this).data('widget'));
});

Si vous devez absolument avoir la valeur d'origine sous forme de chaîne, vous devez utiliser .attr():

HTML:
<a id="foo" href="#" data-color="ABC123"></a>
<a id="bar" href="#" data-color="654321"></a>
JS:
$('#foo').data('color').length; //6
$('#bar').data('color').length; //undefined, length isn't a property of numbers

$('#foo').attr('data-color').length; //6
$('#bar').attr('data-color').length; //6

C'était un exemple artificiel. Pour stocker des valeurs de couleur, j'avais l'habitude d'utiliser la notation hexadécimale numérique (c'est-à-dire 0xABC123), mais il est à noter que hex a été analysé incorrectement dans les versions de jQuery avant 1.7.2, et n'est plus analysé dans un Number à partir de jQuery 1.8 rc 1.

jQuery 1.8 rc 1 a changé le comportement de l'auto-casting. Avant, tout format qui était une représentation valide d'un Number serait jeté à Number. Maintenant, les valeurs qui sont numériques sont seulement auto-cast si leur représentation reste la même. Ceci est mieux illustré avec un exemple.

HTML:
<a id="foo"
    href="#"
    data-int="1000"
    data-decimal="1000.00"
    data-scientific="1e3"
    data-hex="0x03e8">foo!</a>
JS:
                              // pre 1.8    post 1.8
$('#foo').data('int');        //    1000        1000
$('#foo').data('decimal');    //    1000   "1000.00"
$('#foo').data('scientific'); //    1000       "1e3"
$('#foo').data('hex');        //    1000     "0x03e8"

Si vous prévoyez d'utiliser des syntaxes numériques alternatives pour accéder aux valeurs numériques, veillez à convertir la valeur en Number d'abord, comme avec un unaire + opérateur.

JS (suite):
+$('#foo').data('hex'); // 1000

712
2017-08-31 19:36



La principale différence entre les deux est l'endroit où il est stocké et comment il est accédé.

$.fn.attr stocke les informations directement sur l'élément dans les attributs qui sont visibles publiquement lors de l'inspection, ainsi que ceux qui sont disponibles à partir de l'API native de l'élément.

$.fn.data stocke les informations dans un ridiculement obscur endroit. Il est situé dans une variable locale fermée appelée data_userqui est une instance d'une fonction définie localement. Cette variable n'est pas accessible directement depuis l'extérieur de jQuery.

Ensemble de données avec attr()

  • accessible depuis $(element).attr('data-name')
  • accessible depuis element.getAttribute('data-name'),
  • si la valeur était sous la forme de data-name également accessible depuis $(element).data(name) et element.dataset['name'] et element.dataset.name
  • visible sur l'élément lors de l'inspection
  • ne peut pas être des objets

Ensemble de données avec .data()

  • accessible seulement de .data(name)
  • pas accessible depuis .attr() ou ailleurs
  • non visible publiquement sur l'élément lors de l'inspection
  • peut être des objets

80
2018-04-27 23:02