Saya perlu memilih elemen berdasarkan nilai yang disimpan dalam objek elemen .data()
. Minimal, saya ingin memilih properti data tingkat atas menggunakan penyeleksi, mungkin seperti ini:
$('a').data("category","music");
$('a:data(category=music)');
Atau mungkin pemilih akan berada dalam format pemilih atribut biasa:
$('a[category=music]');
Atau dalam format atribut, tetapi dengan specifier untuk menunjukkannya ada di .data()
:
$('a[:category=music]');
Saya menemukan implementasi James Padolsey terlihat sederhana, namun bagus. Format pemilih di atas metode mirror ditunjukkan pada halaman itu. Ada juga patch Sizzle ini .
Untuk beberapa alasan, saya ingat pernah membaca beberapa waktu lalu bahwa jQuery 1.4 akan menyertakan dukungan untuk penyeleksi pada nilai-nilai dalam .data()
objek jquery . Namun, sekarang saya sedang mencarinya, saya tidak dapat menemukannya. Mungkin itu hanya permintaan fitur yang saya lihat. Apakah ada dukungan untuk ini dan saya tidak melihatnya?
Idealnya, saya ingin mendukung sub-properti dalam data () menggunakan notasi titik. Seperti ini:
$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');
Saya juga ingin mendukung beberapa penyeleksi data, di mana hanya elemen dengan SEMUA pemilih data yang ditentukan yang ditemukan. Pemilih berganda jquery biasa melakukan operasi ATAU. Misalnya, $('a.big, a.small')
pilih a
tag dengan kelas big
atau small
). Saya mencari DAN, mungkin seperti ini:
$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');
Terakhir, akan lebih bagus jika operator perbandingan dan fitur regex tersedia pada pemilih data. Jadi $(a[:artist.id>5000])
mungkin saja. Saya menyadari saya mungkin bisa melakukan banyak hal menggunakan ini filter()
, tetapi akan menyenangkan untuk memiliki format pemilih yang sederhana.
Solusi apa yang tersedia untuk melakukan ini? Apakah Jame's Padolsey adalah solusi terbaik saat ini? Perhatian saya terutama dalam hal kinerja, tetapi juga dalam fitur tambahan seperti notasi titik sub-properti dan beberapa pemilih data. Apakah ada implementasi lain yang mendukung hal-hal ini atau lebih baik dalam beberapa hal?
sumber
Jawaban:
Saya telah membuat
data
pemilih baru yang memungkinkan Anda untuk melakukan query dan kondisi bersarang. Pemakaian:Polanya adalah:
"operator" dan "centang" adalah opsional. Jadi, jika Anda hanya memiliki
:data(a.b.c)
itu hanya akan memeriksa truthiness daria.b.c
.Anda dapat melihat operator yang tersedia dalam kode di bawah ini. Di antara mereka adalah
~=
yang memungkinkan pengujian regex:Saya sudah mengujinya dengan beberapa variasi dan sepertinya berfungsi cukup baik. Saya mungkin akan menambahkan ini sebagai repo Github segera (dengan test suite lengkap), jadi tetap perhatikan!
Kode:
sumber
$("a:data(condition),a:data(orCondition)")
... itu akan memiliki efek yang sama. Semakin banyak fitur yang Anda tambahkan, semakin lambat. Jika logikanya kompleks, maka gunakan$(foo).filter(function(){...})
.jQuery.data
, yang tidak mendapatkan data yang ditentukan dalam atribut HTML5. Jika Anda ingin fungsi itu, Anda dapat mengubahjQuery.data
ke$('selector').data
, tapi itu trade off untuk kecepatan.Saat ini saya memilih seperti ini:
Yang sepertinya berfungsi dengan baik, tetapi alangkah baiknya jika jQuery dapat memilih oleh atribut itu tanpa awalan 'data-'.
Saya belum menguji ini dengan data yang ditambahkan ke elemen melalui jQuery secara dinamis, sehingga bisa menjadi kejatuhan metode ini.
sumber
Anda juga dapat menggunakan fungsi penyaringan sederhana tanpa plugin apa pun. Ini bukan apa yang Anda inginkan tetapi hasilnya sama:
sumber
filter
fungsi traversal dapat menerima fungsi tes =) terima kasihSaya ingin memperingatkan Anda bahwa
$('a[data-attribute=true]')
itu tidak berfungsi, sesuai jawaban Ashley, jika Anda melampirkan data ke elemen DOM melalui fungsi data ().Ini berfungsi seperti yang Anda harapkan jika Anda menambahkan data-attr aktual dalam HTML Anda, tetapi jQuery menyimpan data dalam memori, sehingga hasil yang Anda dapatkan dari
$('a[data-attribute=true]')
tidak benar.Anda harus menggunakan plugin data http://code.google.com/p/jquerypluginsblog/ , menggunakan
filter
solusi Dmitri , atau melakukan $ .each semua elemen dan periksa. Data () secara iteratifsumber
Ada
:data()
plugin filter yang melakukan ini :)Beberapa contoh berdasarkan pertanyaan Anda:
Kinerja tidak akan menjadi sangat hebat dibandingkan dengan apa yang mungkin , memilih
$._cache
dan mengambil elemen yang sesuai sejauh ini adalah yang tercepat, tetapi jauh lebih banyak tentang dan tidak terlalu "jQuery-ey" dalam hal bagaimana Anda mendapatkan barang (Anda biasanya datang dari sisi elemen). Dari atas kepala saya, saya tidak yakin ini tercepat karena proses pergi dari ID unik ke elemen berbelit-belit dalam hal kinerja.Selektor perbandingan yang Anda sebutkan akan paling baik dilakukan di a
.filter()
, tidak ada dukungan bawaan untuk ini di plugin, meskipun Anda bisa menambahkannya tanpa banyak masalah.sumber
data-*
atribut HTML5 dan memilihnya akan lebih cepat daripada memilih pada.data()
properti? Juga, ada ide di mana saya bisa mengetahui lebih lanjut tentang $ ._ cache? Saya mencari di Google untuk itu, tetapi tidak menemukan banyak.$.cache
bukan$._cache
, Anda bisa melihat bagaimana itu diterapkan dan digunakan dalam jQuery core di sini: github.com/jquery/jquery/blob/master/src/data.js#L4 Ketika Anda menyebut.data()
itu sebenarnya menyimpannya sebagai objek di$.cache[elementUniqueID]
, yang merupakan ID yang diberikan sesuai kebutuhan dengan cara tambahan untuk setiap elemen, misalnya, 1, 2, 3, dll. ID pendakian itu akan diekspos di jQuery 1.4.3 Saya percaya, berdasarkan komentar git beberapa hari yang lalu. Saya menganggap rute HTML 5 akan lebih cepat, tergantung optimasi browser apa yang tersedia (saya yakin akan tersedia lebih banyak).Anda dapat mengatur
data-*
atribut pada elm menggunakanattr()
, dan kemudian pilih menggunakan atribut itu:dan sekarang untuk elm itu, keduanya
attr()
dandata()
akan menghasilkan 123 :Namun, jika Anda memodifikasi nilai menjadi 456 menggunakan
attr()
,data()
masih akan menjadi 123 :Jadi seperti yang saya mengerti, sepertinya Anda mungkin harus menghindari percampuran
attr()
dandata()
perintah dalam kode Anda jika Anda tidak perlu. Karenaattr()
sepertinya berhubungan langsung dengan DOM sedangkandata()
berinteraksi dengan 'memori', meskipun nilai awalnya bisa dari DOM. Tetapi poin kuncinya adalah bahwa keduanya belum tentu sinkron sama sekali.Jadi berhati-hatilah.
Bagaimanapun, jika Anda tidak mengubah
data-*
atribut di DOM atau di memori, maka Anda tidak akan memiliki masalah. Segera setelah Anda mulai mengubah nilai adalah saat potensi masalah dapat muncul.Terima kasih kepada @Clarence Liu atas jawaban @ Ash, dan juga pos ini .
sumber
Berhasil. Lihat Pemilih Atribut Setara [nama = ”nilai”] .
sumber
Jika Anda juga menggunakan jQueryUI, Anda mendapatkan versi
:data
pemilih (sederhana) yang memeriksa keberadaan item data, sehingga Anda dapat melakukan sesuatu seperti$("div:data(view)")
, atau$( this ).closest(":data(view)")
.Lihat http://api.jqueryui.com/data-selector/ . Saya tidak tahu sudah berapa lama mereka memilikinya, tetapi sekarang sudah ada di sana!
sumber
Ini adalah plugin yang menyederhanakan https://github.com/rootical/jQueryDataSelector
Gunakan seperti itu:
sumber