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.