Elemento di filtro in base alla chiave / valore .data ()


116

Supponiamo di avere 4 elementi div con class .navlink, che, quando cliccati, usano .data()per impostare una chiave chiamata 'selected', su un valore di true:

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

Ogni volta che si .navlinkfa clic su un nuovo , vorrei memorizzare quello precedentemente selezionato navlinkper una successiva manipolazione. Esiste un modo semplice e veloce per selezionare un elemento in base a ciò che è stato memorizzato utilizzando .data()?

Sembra che non ci siano filtri jQuery : che si adattano al conto e ho provato quanto segue (all'interno dello stesso evento clic), ma per qualche motivo non funziona:

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

So che ci sono altri modi per ottenere questo risultato, ma in questo momento sono per lo più solo curioso di sapere se può essere fatto tramite .data().

Risposte:


192

il filtro funzionerebbe, ma è necessario restituire true sugli oggetti corrispondenti nella funzione passata al filtro affinché possa catturarli.

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

6
Si prega di notare che questo non è più l'unico modo per farlo, StefanoP ha fornito delle alternative
Nathan Koop

3
@NathanKoop, non proprio. Vedi il mio commento sulla sua risposta.
Bryan Downing

Per coloro che utilizzano un attributo di dati per trovare un elemento altrimenti non individuabile (id meno div ecc ... a cui è necessario poter accedere per qualsiasi motivo) in qualsiasi posizione nel documento:$("*").filter(function() { return $(this).data("DATA IDENTIFIER HERE") == DATA VALUE HERE; });
Tschallacka

questo non è "disordinato" - questo è l'unico modo sicuro per filtrare in termini arbitrari senza richiedere di "sfuggire" a quei valori per garantire che la concatenazione del termine di ricerca con il resto del selettore non crei un selettore illegale.
Alnitak

145

Solo per la cronaca, puoi filtrare i dati con jquery (questa domanda è piuttosto vecchia e jQuery si è evoluta da allora, quindi è giusto scrivere anche questa soluzione):

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

o, meglio (per le prestazioni):

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

oppure, se vuoi ottenere tutti gli elementi con data-selectedset:

$('[data-selected]')

Nota che questo metodo funzionerà solo con i dati che sono stati impostati tramite attributi html. Se imposti o modifichi i dati con la .data()chiamata, questo metodo non funzionerà più.


9
se il basso numero di voti per questa risposta spaventa voi - è la risposta accettata con 100 voti per una domanda praticamente identico stackoverflow.com/questions/4146502
Simon_Weaver

48
-1 Questo non funziona quando i dati sono impostati con il .data()metodo invece che con un data-attributo. Vedi questo violino: jsfiddle.net/bryandowning/tySWC - Inoltre, il .find()metodo cerca i figli del selettore precedente. Nell'esempio fornito, data-selectedè un attributo di .navlink, non un figlio di .navlink. Inoltre, $('div p')e $('div').find('p')sono essenzialmente equivalenti. L'uso .find()sembra che potrebbe essere più lento a causa della chiamata di funzione extra (anche se non sono positivo su questo). Per favore correggimi se sbaglio su qualcosa (vorrei davvero che questo metodo funzionasse).
Bryan Downing

3
un paio di cose: 1) hai ragione che questo non funziona se imposti i dati con .data(), dato che jQuery cerca attraverso il DOM, l'ho postato per chi (come me) è arrivato a questa domanda per altri motivi; 2) corretto, .find()cerca tra i bambini, quindi è sbagliato in questo esempio; 3) ti sbagli, non sono equivalenti, in quanto jQuery cerca da destra a sinistra, vedi jonraasch.com/blog/…
StefanoP

2
Un voto $('[data-selected]')positivo mi ha aiutato per qualcosa come$('ul.categories a[data-categories_id]').click(......);
Luke Cousins

Inoltre, sembra che se aggiorni l'attributo data usando .attr, se lo recuperi usando .data il valore non verrà aggiornato - quindi fai attenzione quando mescoli i due
Fabio Lolli

13

Possiamo creare un plugin abbastanza facilmente:

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

Utilizzo (controllo di un pulsante di opzione):

$('input[name=location_id]').filterData('my-data','data-val').prop('checked',true);

Intendi il metodo del plugin, altrimenti questa è la stessa della risposta accettata ...
jave.web

@ jave.web Infatti. Ma non tutti sanno come trasformarlo in un plugin. Verbosità aggiornata.
mpen

non fraintendetemi, la vostra risposta è fantastica, tuttavia le parole qui sono molto importanti, grazie per l'aggiornamento :)
jave.web

8

Ho notato due cose (potrebbero essere errori da quando l'hai annotato).

  1. Hai perso un punto nel primo esempio ( $('.navlink').click)
  2. Perché il filtro funzioni, devi restituire un valore ( return $(this).data("selected")==true)

-1

Sembra più lavoro del suo valore.

1) Perché non avere solo una singola variabile JavaScript che memorizza un riferimento all'oggetto \ jQuery attualmente selezionato.

2) Perché non aggiungere una classe all'elemento attualmente selezionato. Quindi potresti interrogare il DOM per la classe ".active" o qualcosa del genere.


Sì, ma come ho detto, sapevo che c'erano altri modi per farlo. Ero solo bloccato sul fatto che potesse essere filtrato tramite data () e perché filter () non funzionava per me. Grazie comunque.
user113716

Scusate. Mi mancava quella parte della tua domanda.
Bryan Migliorisi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.