Elemen filter berdasarkan kunci / nilai .data ()

116

Katakanlah saya memiliki 4 elemen div dengan kelas .navlink, yang, ketika diklik, gunakan .data()untuk menyetel kunci yang dipanggil 'selected', ke nilai true:

$('.navlink')click(function() { $(this).data('selected', true); })

Setiap kali yang baru .navlinkdiklik, saya ingin menyimpan yang sebelumnya dipilih navlinkuntuk manipulasi nanti. Adakah cara cepat dan mudah untuk memilih elemen berdasarkan apa yang disimpan menggunakan .data()?

Sepertinya tidak ada jQuery : filter yang sesuai dengan tagihan, dan saya mencoba yang berikut (dalam peristiwa klik yang sama), tetapi untuk beberapa alasan tidak berhasil:

var $previous = $('.navlink').filter( 
    function() { $(this).data("selected") == true }
);

Saya tahu bahwa ada cara lain untuk mencapai ini, tetapi saat ini saya hanya ingin tahu apakah itu dapat dilakukan melalui .data().

pengguna113716
sumber

Jawaban:

192

filter Anda akan berfungsi, tetapi Anda harus mengembalikan nilai true pada objek yang cocok dalam fungsi yang diteruskan ke filter untuk mengambilnya.

var $previous = $('.navlink').filter(function() { 
  return $(this).data("selected") == true 
});
Kucing Barok
sumber
6
Harap dicatat bahwa ini bukan lagi satu-satunya cara untuk melakukan ini, StefanoP telah menyediakan alternatif
Nathan Koop
3
@NathanKoop, kurang tepat. Lihat komentar saya atas jawabannya.
Bryan Downing
Bagi mereka yang menggunakan atribut data untuk menemukan elemen yang tidak dapat ditemukan (div id kurang dll ... yang Anda perlukan untuk dapat mengakses untuk alasan apa pun) di lokasi mana pun dalam dokumen:$("*").filter(function() { return $(this).data("DATA IDENTIFIER HERE") == DATA VALUE HERE; });
Tschallacka
ini tidak "berantakan" - ini adalah satu-satunya cara aman untuk memfilter istilah arbitrer tanpa mengharuskan Anda "keluar" dari nilai tersebut untuk memastikan bahwa penggabungan istilah penelusuran dengan pemilih lainnya tidak membuat pemilih ilegal.
Alnitak
145

Sekadar catatan, Anda dapat memfilter data dengan jquery (pertanyaan ini cukup lama, dan jQuery berevolusi sejak saat itu, jadi tepat untuk menulis solusi ini juga):

$('.navlink[data-selected="true"]');

atau, lebih baik (untuk kinerja):

$('.navlink').filter('[data-selected="true"]');

atau, jika Anda ingin mendapatkan semua elemen dengan data-selectedset:

$('[data-selected]')

Perhatikan bahwa metode ini hanya akan berfungsi dengan data yang disetel melalui atribut html. Jika Anda menyetel atau mengubah data dengan .data()panggilan tersebut, metode ini tidak akan berfungsi lagi.

StefanoP
sumber
9
jika jumlah suara yang rendah untuk jawaban ini membuat Anda takut - itu adalah jawaban yang diterima dengan 100+ suara untuk pertanyaan yang hampir identik stackoverflow.com/questions/4146502
Simon_Weaver
48
-1 Ini tidak berfungsi saat data disetel dengan .data()metode alih-alih data-atribut. Lihat biola ini: jsfiddle.net/bryandowning/tySWC - Selain itu, .find()metode ini mencari turunan dari pemilih sebelumnya. Dalam contoh yang diberikan, data-selectedadalah atribut dari .navlink, bukan anak dari .navlink. Juga, $('div p')dan $('div').find('p')pada dasarnya setara. Menggunakan .find()sepertinya itu mungkin lebih lambat karena pemanggilan fungsi tambahan (meskipun saya tidak yakin tentang ini). Harap perbaiki saya jika saya salah tentang semua ini (Saya sangat berharap metode ini berhasil).
Bryan Downing
3
beberapa hal: 1) Anda benar bahwa ini tidak berfungsi jika Anda menyetel data dengan .data(), karena jQuery mencari melalui DOM, saya mempostingnya untuk mereka (seperti saya) yang mendapatkan pertanyaan ini karena alasan lain; 2) benar, .find()pencarian melalui anak-anak, jadi salah dalam contoh ini; 3) Anda salah, mereka tidak setara, karena jQuery mencari dari kanan ke kiri, lihat jonraasch.com/blog/…
StefanoP
2
Suara untuk $('[data-selected]')itu membantu saya keluar untuk sesuatu seperti$('ul.categories a[data-categories_id]').click(......);
Luke Cousins
Selain itu, sepertinya jika Anda memperbarui atribut data menggunakan .attr, jika Anda mengambilnya menggunakan .data, nilainya tidak akan diperbarui - jadi berhati-hatilah saat mencampur keduanya
Fabio Lolli
13

Kita bisa membuat plugin dengan cukup mudah:

$.fn.filterData = function(key, value) {
    return this.filter(function() {
        return $(this).data(key) == value;
    });
};

Penggunaan (memeriksa tombol radio):

$('input[name=location_id]').filterData('my-data','data-val').prop('checked',true);
mpen
sumber
Maksud Anda metode plugin jika tidak, ini sama dengan jawaban yang diterima ...
jave.web
@ jave.web Memang. Namun tidak semua orang tahu bagaimana mengubahnya menjadi sebuah plugin. Verbiage diperbarui.
mpen
jangan salah sangka, jawaban Anda bagus, namun kata-kata di sini sangat penting, terima kasih atas pembaruannya :)
jave.web
8

Dua hal yang saya perhatikan (mungkin saja kesalahan sejak Anda menuliskannya).

  1. Anda melewatkan satu titik di contoh pertama ( $('.navlink').click)
  2. Agar filter berfungsi, Anda harus mengembalikan nilai ( return $(this).data("selected")==true)
Thomas
sumber
-1

Kedengarannya lebih banyak pekerjaan daripada nilainya.

1) Mengapa tidak hanya memiliki satu variabel JavaScript yang menyimpan referensi ke objek elemen \ jQuery yang saat ini dipilih.

2) Mengapa tidak menambahkan kelas ke elemen yang saat ini dipilih. Kemudian Anda dapat meminta DOM untuk kelas ".active" atau sesuatu.

Bryan Migliorisi
sumber
Ya, tapi seperti yang saya katakan, saya tahu ada cara lain untuk mencapainya. Saya hanya terjebak pada apakah itu bisa difilter melalui data (), dan mengapa filter () tidak berfungsi untuk saya. Terimakasih Meskipun.
pengguna113716
Maaf. Saya melewatkan bagian pertanyaan Anda itu.
Bryan Migliorisi