Usando il selettore 'inizia con' sui nomi delle singole classi


158

Se ho il seguente:

<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

Posso usare il seguente selettore per trovare i primi due DIV:

$("div[class^='apple-']")

Tuttavia, se ho questo:

<div class="some-other-class apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

Troverà solo il secondo DIV, poiché la classe del primo div viene restituita come stringa (penso) e in realtà non inizia con 'apple-' ma piuttosto 'some-'

Un modo per aggirare il problema è non iniziare, ma contiene invece:

$("div[class*='apple-']")

Il problema è che selezionerà anche il 3 ° DIV nel mio esempio.

Domanda: tramite jQuery, qual è il modo corretto di utilizzare i selettori di predicati sui nomi delle singole classi, anziché l'intero attributo della classe come stringa? Si tratta solo di afferrare la CLASS, quindi di dividerla in un array e quindi di ripercorrere ogni singolo con regex? Oppure esiste una soluzione più elegante / meno dettagliata?

Risposte:


304

Classi che iniziano con "apple-" più le classi che contengono "apple-"

$("div[class^='apple-'],div[class*=' apple-']")

5
+1. Anche se concordo con il suggerimento di @parrots che "apple" dovrebbe essere la sua classe qui, dal momento che ovviamente si sovrappone a più div ma è un'entità distinta. Ma questo risolve il problema.
jvenema,

Hmm ... intelligente! Non avevo pensato di usare lo spazio lì dentro. Si possono usare operatori booleani in un selettore jquery? Idealmente, quanto sopra sarebbe 'OR' per evitare il caso (raro e probabilmente evitabile) in cui ci sono più di una classe che fissa con 'apple-'
DA.

Non sono sicuro di aver capito, ma se vuoi usare il secondo selettore solo quando il primo selettore restituisce zero elementi, potresti fare qualcosa del genere: var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Josh Stodola,

ora che ci penso, la tua soluzione iniziale funziona perfettamente. Un DIV che aveva una classe come "apple-brick apple-horse" sarebbe ancora stato selezionato una volta nell'oggetto jQuery.
DA.

usa * invece di div se non limiti la classe per un elemento specifico :)
Hidayt Rahman,

13

Consiglierei di fare "mela" nella sua classe. Se possibile, dovresti evitare l'inizio-con / termina-con, perché essere in grado di selezionare l'utilizzo div.applesarebbe molto più veloce. Questa è la soluzione più elegante. Non aver paura di dividere le cose in classi separate se il compito è più semplice / veloce.


Come pensi che sarebbe molto più veloce? Deve ancora scansionare l'intero DOM e valutare l'attributo di classe. Sarebbe leggermente più veloce (nella migliore delle ipotesi) perché non dovrebbe sottostrare l'attributo di classe. Trascurabile.
Josh Stodola,

2
componenthouse.com/article-19 : se guardi nella sezione get by class, l'uso della normale sintassi dei punti è in genere un po 'più veloce del trattamento della classe come un attributo. Aggiungi la ricerca della sottostringa (e il lavoro aggiuntivo che dovrà fare per scomporre elementi con più nomi di classe) e si sommerà a un discreto risparmio sulle prestazioni.
Pappagalli

1
Sono d'accordo. Il problema è che stiamo ancora supportando pesantemente IE6 e non supporta i selettori composti nei CSS: .class1.class2.class3 in quanto tale, stiamo facendo affidamento sull'uso di nomi di classe più lunghi in cui i 'parametri' sono divisi da trattini.
DA.

6

questo è per il prefisso con

$("div[class^='apple-']")

questo è per cominciare, quindi non è necessario avere il carattere "-" lì dentro

$("div[class|='apple']")

puoi trovare un sacco di altre interessanti varianti del selettore jQuery qui https://api.jquery.com/category/selectors/


6

Mentre la risposta principale qui è una soluzione alternativa per il caso particolare del richiedente, se stai cercando una soluzione per utilizzare effettivamente "inizia con" sui nomi delle singole classi:

È possibile utilizzare questo selettore jQuery personalizzato, che chiamo :acp()"A Class Prefix". Il codice è in fondo a questo post.

var test = $('div:acp("starting_text")');

Questo selezionerà tutti gli <div>elementi che hanno almeno un nome di classe che inizia con la stringa data ("starting_text" in questo esempio), indipendentemente dal fatto che quella classe sia all'inizio o altrove nelle stringhe dell'attributo di classe.

<div id="1" class="apple orange lemon" />
<div id="2" class="orange applelemon banana" />
<div id="3" class="orange lemon apple" />
<div id="4" class="lemon orangeapple" />
<div id="5" class="lemon orange" />

var startsWithapp = $('div:acp("app")');

Ciò restituirà gli elementi 1, 2 e 3, ma non 4 o 5.

Ecco la dichiarazione per il :acpselettore personalizzato, che puoi inserire ovunque:

$(function(){
    $.expr[":"].acp = function(elem, index, m){
          var regString = '\\b' + m[3];
          var reg = new RegExp(regString, "g");
          return elem.className.match(reg);
    }
});

L'ho fatto perché faccio un sacco di hacking GreaseMonkey di siti Web su cui non ho alcun controllo back-end, quindi ho spesso bisogno di trovare elementi con nomi di classe che abbiano suffissi dinamici. È stato molto utile


2

Prova questo:

$("div[class]").filter(function() {
    var classNames = this.className.split(/\s+/);
    for (var i=0; i<classNames.length; ++i) {
        if (classNames[i].substr(0, 6) === "apple-") {
            return true;
        }
    }
    return false;
})

2
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

in questo caso come risposta Josh Stodola è corretta Le classi che iniziano con "apple-" più le classi che contengono "apple-"

$("div[class^='apple-'],div[class*=' apple-']")

ma se l'elemento ha più classi come questa

<div class="some-class apple-monkey"></div>
<div class="some-class apple-horse"></div>
<div class="some-class cow-apple-brick"></div>

allora la soluzione di Josh Stodola non funzionerà
per questo, bisogna fare qualcosa del genere

$('.some-parent-class div').filter(function () {
  return this.className.match(/\bapple-/);// this is for start with
  //return this.className.match(/apple-/g);// this is for contain selector
}).css("color","red");

forse aiuta qualcun altro grazie


0

Se un elemento ha classi multiple "[class ^ = 'apple-']" non funziona, ad es

<div class="fruits apple-monkey"></div>

L'OP ne parla nella domanda.
Oca,
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.