jQuery Data vs Attr?

513

Was ist der Unterschied in der Verwendung zwischen $.dataund $.attrbei der Verwendung data-someAttribute?

Meines Wissens nach wird das $.datain jQuery's gespeichert $.cache, nicht im DOM. Daher sollte ich verwenden, wenn ich $.cachefür die Datenspeicherung verwenden möchte $.data. Wenn ich HTML5-Datenattribute hinzufügen möchte, sollte ich verwenden $.attr("data-attribute", "myCoolValue").

John B.
quelle
5
Bitte lesen Sie dies: forum.jquery.com/topic/when-to-use-attr-vs-data
Baz1nga
14
@zzz Außer dass es die Frage nicht wirklich zu beantworten scheint ...?
sdleihssirhc
2
Eigentlich indirekt. Das Anhängen eines Objekts über attr()kann zu Speicherverlusten führen (zumindest im Internet Explorer), während die Verwendung data()sicher ist. Er weist in seiner Antwort darauf hin, obwohl er nicht ausdrücklich herauskommt und es sagt. Weitere Informationen zu den jQuery-Dokumenten (siehe "Zusätzliche Hinweise"): api.jquery.com/attr
ken
6
@ John B, nur zu Ihrer Information (obwohl dies alt ist), das Datenattribut von data-someAttributeist ungültig; Gemäß Spezifikation ist nur Kleinbuchstaben zulässig. Sie werden auf eine Vielzahl von seltsamen Problemen stoßen, wenn Sie Zeichen in Großbuchstaben verwenden.
Ken
1
@AdrienBe Viele Referenzen leicht über die Suche zu finden, aber da ich gelangweilt bin, gehen Sie hier: stackoverflow.com/a/22753630/84473
Ken

Antworten:

748

Wenn Sie Daten vom Server an ein DOM-Element übergeben, sollten Sie die Daten für das Element festlegen:

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

Auf die Daten kann dann .data()in jQuery zugegriffen werden :

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

Allerdings , wenn Sie Daten auf einem DOM - Knoten in jQuery speichern unter Verwendung von Daten, werden die Variablen auf dem Knoten gespeichert Objekt . Dies ist komplexe Objekte und Referenzen , wie die Speicherung der Daten auf dem Knoten aufzunehmen Element als Attribut wird nur Stringwerte aufzunehmen.

Fortsetzung meines Beispiels von oben:
$('#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

Außerdem hat die Namenskonvention für Datenattribute ein verstecktes "Gotcha":

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

Der mit Bindestrich versehene Schlüssel funktioniert weiterhin:

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"

Für das von zurückgegebene Objekt ist .data()jedoch kein getrennter Schlüssel festgelegt:

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

Aus diesem Grund empfehle ich, den mit Bindestrich versehenen Schlüssel in Javascript zu vermeiden.

Verwenden Sie für HTML weiterhin das mit Bindestrich versehene Formular. HTML - Attribute sollen erhalten ASCII-Kleinbuchstaben automatisch , so <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>und <dIv DaTa-FoObAr></DiV>sind angeblich als identisch behandelt werden, aber für die beste Kompatibilität der unteren Gehäuseform bevorzugt werden sollte.

Die .data()Methode führt auch ein grundlegendes Auto-Casting durch, wenn der Wert mit einem erkannten Muster übereinstimmt:

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']}`

Diese Auto-Casting-Funktion ist sehr praktisch, um Widgets und Plugins zu instanziieren:

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

Wenn Sie unbedingt den ursprünglichen Wert als Zeichenfolge haben müssen, müssen Sie Folgendes verwenden .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

Dies war ein erfundenes Beispiel. Zum Speichern von Farbwerten habe ich die numerische Hex-Notation (dh 0xABC123) verwendet, aber es ist erwähnenswert, dass Hex in jQuery-Versionen vor 1.7.2 falsch analysiert wurde und ab NumberjQuery 1.8 rc 1 nicht mehr in a analysiert wird .

jQuery 1.8 rc 1 hat das Verhalten des automatischen Castings geändert . Zuvor wurde jedes Format, das eine gültige Darstellung von a war Number, umgewandelt Number. Jetzt werden numerische Werte nur dann automatisch umgewandelt, wenn ihre Darstellung gleich bleibt. Dies lässt sich am besten anhand eines Beispiels veranschaulichen.

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"

Wenn Sie alternative numerische Syntaxen für den Zugriff auf numerische Werte verwenden möchten, müssen Sie den Wert in einen Numberersten Wert umwandeln, z. B. mit einem unären +Operator.

JS (Forts.):
+$('#foo').data('hex'); // 1000
zzzzBov
quelle
17
@vitorbal, während dies wahr ist, das Objekt zurückgegeben durch .data()wird nicht die Bindestriche Form gesetzt haben, so $('#bar').data('foo-bar-baz')funktionieren wird, aber $('#bar').data()['foo-bar-baz']nicht. Aus diesem Grund schlage ich vor, dass die Leute die Verwendung der Form mit Bindestrich vermeiden.
zzzzBov
1
ok, jetzt verstehe ich was du meinst. Wusste nichts über dieses kleine Detail, danke für das Update :)
vitorbal
1
@SableFoste, welcher Link? api.jquery.com/data ist der richtige Link für die Methode und hat sich meines Wissens nicht geändert.
zzzzBov
1
Ich mag, Foo, Bar, Baz, Fizz, Buzz mehr: D
Usman Younas
1
Liebe jede Zeile.
Foo Bar
108

Der Hauptunterschied zwischen den beiden besteht darin, wo es gespeichert ist und wie darauf zugegriffen wird.

$.fn.attr speichert die Informationen direkt auf dem Element in Attributen, die bei der Überprüfung öffentlich sichtbar sind und auch über die native API des Elements verfügbar sind.

$.fn.dataspeichert die Informationen an einem lächerlich dunklen Ort. Es befindet sich in einer geschlossenen lokalen Variablen, data_userdie als Instanz einer lokal definierten Funktion Data bezeichnet wird. Auf diese Variable kann von außerhalb von jQuery nicht direkt zugegriffen werden.

Datensatz mit attr()

  • zugänglich von $(element).attr('data-name')
  • zugänglich von element.getAttribute('data-name'),
  • wenn der Wert in Form von data-nameauch zugänglich von $(element).data(name)und element.dataset['name']und warelement.dataset.name
  • bei der Inspektion auf dem Element sichtbar
  • kann kein Objekt sein

Datensatz mit .data()

  • nur zugänglich von.data(name)
  • nicht zugänglich von .attr()oder irgendwo anders
  • bei Inspektion auf dem Element nicht öffentlich sichtbar
  • können Objekte sein
Travis J.
quelle
2
Ja, meine Hauptfrage war, wo diese Daten gespeichert wurden, also danke für diese Info!
Max Wilder
2
Auch .attr()ist der Weg zu gehen, wenn danach Sie verwenden mögen Daten als Selektor ( .data()wird nicht gefunden, siehe codepen.io/anon/pen/EvawPV?editors=1011 )
Kamafeather
1

Sie können data-*Attribute verwenden, um benutzerdefinierte Daten einzubetten. Die data-*Attribute geben uns die Möglichkeit, benutzerdefinierte Datenattribute in alle HTML-Elemente einzubetten.

Mit der jQuery- .data()Methode können Sie Daten eines beliebigen Typs für DOM-Elemente auf eine Weise abrufen / festlegen, die vor Zirkelverweisen und damit vor Speicherlecks geschützt ist.

jQuery- .attr()Methode Attributwert abrufen / festlegen nur für das erste Element in der übereinstimmenden Gruppe.

Beispiel:

<span id="test" title="foo" data-kind="primary">foo</span>

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");
Yogendra Chauhan
quelle