jQuery Data vs Attr?

513

Apa perbedaan penggunaan antara $.datadan $.attrsaat menggunakan data-someAttribute?

Pemahaman saya adalah yang $.datadisimpan dalam jQuery $.cache, bukan DOM. Karena itu, jika saya ingin menggunakan $.cacheuntuk penyimpanan data, saya harus menggunakannya $.data. Jika saya ingin menambahkan atribut data HTML5, saya harus menggunakan $.attr("data-attribute", "myCoolValue").

John B
sumber
14
@zzz Kecuali itu sepertinya tidak benar-benar menjawab pertanyaan ...?
sdleihssirhc
2
Sebenarnya tidak, secara tidak langsung. Melampirkan objek melalui attr()dapat menyebabkan kebocoran memori (setidaknya di IE), saat menggunakan data()aman. Dia mengisyaratkan hal ini dalam jawabannya meskipun dia tidak secara eksplisit keluar dan mengatakannya. Info lebih lanjut tentang dokumen jQuery (lihat "Catatan Tambahan"): api.jquery.com/attr
ken
6
@ John B, hanya FYI (meskipun ini sudah tua), atribut data data-someAttributetidak valid; per spek, hanya huruf kecil yang diizinkan. Anda akan menemui banyak sekali masalah aneh dengan menggunakan karakter huruf besar.
ken
1
@AdrienBe Banyak referensi mudah ditemukan melalui pencarian, tapi karena saya bosan, ini dia: stackoverflow.com/a/22753630/84473
ken

Jawaban:

748

Jika Anda meneruskan data ke elemen DOM dari server, Anda harus mengatur data pada elemen:

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

Data kemudian dapat diakses menggunakan .data()di jQuery:

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

Namun ketika Anda menyimpan data pada simpul DOM di jQuery menggunakan data, variabel disimpan pada objek simpul . Ini untuk mengakomodasi objek dan referensi yang kompleks karena menyimpan data pada elemen node sebagai atribut hanya akan mengakomodasi nilai string.

Melanjutkan contoh saya dari atas:
$('#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

Juga, konvensi penamaan untuk atribut data memiliki sedikit "gotcha" tersembunyi:

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

Kunci yang ditulis dgn tanda penghubung masih akan bekerja:

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"

Namun objek yang dikembalikan oleh .data()tidak akan memiliki set kunci ditulis dgn tanda penghubung:

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

Karena alasan inilah saya menyarankan untuk menghindari kunci ditulis dgn tanda penghubung dalam javascript.

Untuk HTML, tetap gunakan formulir ditulis dgn tanda penghubung. Atribut HTML seharusnya mendapatkan ASCII-lowercased otomatis , sehingga <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>, dan <dIv DaTa-FoObAr></DiV>yang seharusnya diperlakukan sebagai identik, tetapi untuk kompatibilitas terbaik bentuk kasus yang lebih rendah harus lebih disukai.

The .data()Metode juga akan melakukan beberapa dasar auto-casting jika nilai cocok dengan pola diakui:

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

Kemampuan auto-casting ini sangat nyaman untuk instantiating widget & plugin:

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

Jika Anda benar-benar harus memiliki nilai asli sebagai string, maka Anda harus menggunakan .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

Ini adalah contoh yang dibuat-buat. Untuk menyimpan nilai warna, saya dulu menggunakan notasi hex numerik (yaitu 0xABC123), tetapi perlu dicatat bahwa hex diurai secara salah dalam versi jQuery sebelum 1.7.2 , dan tidak lagi diurai menjadi Numberseperti pada jQuery 1.8 rc 1.

jQuery 1.8 rc 1 mengubah perilaku auto-casting . Sebelum, format itu adalah representasi yang sah dari Numberakan dilemparkan ke Number. Sekarang, nilai-nilai yang numerik hanya auto-cast jika representasi mereka tetap sama. Ini paling baik digambarkan dengan sebuah contoh.

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"

Jika Anda berencana untuk menggunakan sintaks numerik alternatif untuk mengakses nilai numerik, pastikan untuk memberikan nilainya ke yang Numberpertama, seperti dengan +operator unary .

JS (lanjutan):
+$('#foo').data('hex'); // 1000
zzzzBov
sumber
17
@ Vitorbal, sementara ini benar, objek yang dikembalikan oleh tidak.data() akan memiliki set bentuk ditulis dgn tanda penghubung, sehingga akan bekerja, tetapi tidak akan. Karena alasan inilah saya menyarankan agar orang-orang menghindari menggunakan bentuk ditulis dgn tanda penghubung. $('#bar').data('foo-bar-baz')$('#bar').data()['foo-bar-baz']
zzzzBov
1
ok, sekarang saya mengerti maksud Anda. Tidak tahu tentang detail kecil itu, terima kasih atas pembaruannya :)
vitorbal
1
@SableFoste, tautan mana? api.jquery.com/data adalah tautan yang benar untuk metode ini, dan tidak berubah sejauh yang saya ketahui.
zzzzBov
1
saya suka, foo, bar, baz, fizz, buzz selengkapnya: D
Usman Younas
1
Cintai setiap baris.
Foo Bar
108

Perbedaan utama antara keduanya adalah di mana ia disimpan dan bagaimana diakses.

$.fn.attr menyimpan informasi secara langsung pada elemen dalam atribut yang dapat dilihat publik setelah inspeksi, dan juga yang tersedia dari API asli elemen tersebut.

$.fn.datamenyimpan informasi di tempat yang sangat tidak jelas . Ini terletak di variabel lokal tertutup data_useryang disebut yang merupakan turunan dari data fungsi yang didefinisikan secara lokal. Variabel ini tidak dapat diakses dari luar jQuery secara langsung.

Kumpulan data dengan attr()

  • dapat diakses dari $(element).attr('data-name')
  • dapat diakses dari element.getAttribute('data-name'),
  • jika nilai itu dalam bentuk data-namejuga dapat diakses dari $(element).data(name)dan element.dataset['name']danelement.dataset.name
  • terlihat pada elemen setelah diperiksa
  • tidak bisa menjadi objek

Kumpulan data dengan .data()

  • hanya dapat diakses dari.data(name)
  • tidak dapat diakses dari .attr()atau di mana pun
  • tidak terlihat secara terbuka pada elemen setelah diperiksa
  • bisa menjadi benda
Travis J
sumber
2
Ya, pertanyaan utama saya adalah di mana data ini disimpan, jadi terima kasih atas info itu!
Max Wilder
2
Juga .attr()merupakan cara untuk pergi, jika setelah itu Anda ingin menggunakan data sebagai pemilih ( .data()tidak akan ditemukan; lihat codepen.io/anon/pen/EvawPV?editors=1011 )
Kamafeather
1

Anda dapat menggunakan data-*atribut untuk menanamkan data khusus. The data-*atribut memberi kita kemampuan untuk data kustom embed atribut pada semua elemen HTML.

.data()Metode jQuery memungkinkan Anda untuk mendapatkan / menyetel data jenis apa pun ke elemen DOM dengan cara yang aman dari referensi melingkar dan karenanya dari kebocoran memori.

.attr()Metode jQuery mendapatkan / menetapkan nilai atribut hanya untuk elemen pertama di set yang cocok.

Contoh:

<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
sumber