2012-12-14 10 views
16

Supponiamo che io ho il seguente codice HTML:Seleziona elemento meno che non abbia un antenato di una data classe utilizzando solo un selettore

<div class="foo"> 
    <ul> 
    <li>One</li> 
    <li>Two</li> 
    </ul> 
</div> <!-- not originally here --> 
<div class="bar"> 
    <ul> 
    <li>Three</li> 
    <li>Four</li> 
    </ul> 
</div> 

voglio selezionare tutti li elementi che sono non discendenti di un elemento con classe foo. So che posso farlo con una fantasia filter function, ma mi chiedo se posso farlo solo con un selettore. Per prima cosa ho provato:

$(":not(.foo) li") 

Purtroppo questo non funziona in quanto la li ha altri antenati senza lo stile (il ul in questo caso). Il seguente sembra funzionare;

$(":not(.foo) :not(.foo) li") 

In altre parole, selezionare tutti li elementi che non hanno antenato che o ha classe foo o ha un antenato proprio con classe foo. Forse questo è il migliore/unico modo per farlo con un selettore, ma non mi entusiasma della ripetizione del selettore :not. Qualche idea migliore là fuori?

fiddle

+2

Il problema qui è che ': non (.foo) li' non significa "'li' che non ha nessun antenato che ha classe' foo'".Significa "' li' che ha un antenato che non ha classe 'pippo'". La differenza sembra sottile, ma in realtà è una grande differenza. – BoltClock

+0

Sì, esattamente. E il secondo significa 'li' che ha un antenato che non ha classe' pippo' E non ha un proprio antenato con la classe 'pippo'. Quale penso sia il risultato giusto, ma è un modo abbastanza brutto e insoddisfacente per arrivarci. –

risposta

24

Si può fare in questo modo

$("li").not('.foo li') 

http://jsfiddle.net/y7s54/

o

$("li:not(.foo li)") 

http://jsfiddle.net/QpCYY/

Seleziona tutti di Li che non hanno un antenato con classe foo

+0

Questa mi sembra la migliore risposta a meno che qualcuno non abbia una tesi in contrario. –

+0

Sono d'accordo; è meglio della mia risposta ul> li. – DNS

0

ne dite di questo:

$("li:not(.foo > li)") 

I commenti nei documenti sono molto utili se questo non funziona:

http://api.jquery.com/not-selector/

+0

no - http://jsfiddle.net/HsPSv/1/ –

+0

Questa è l'idea di base giusta, ma non funziona, dal momento che i lettori non sono diretti discendenti di .foo. – DNS

4

Prova li:not(.foo > ul > li); che seleziona tutti gli assi meno quelli con un genitore.

+0

Non sono sicuro del perché OP non sia * entusiasta della ripetizione del selettore ': not' *. Quello che hai scritto probabilmente va bene in JQuery/Sizzle, ma secondo le specifiche CSS3, il selettore ': not' può contenere solo [selettori semplici] (http://www.w3.org/TR/css3-selectors/ # semplici-selettori-DFN). – kojiro

+0

@kojiro: Probabilmente perché ripetere il selettore ': not' in un modo conforme a CSS3 [in realtà non funziona] (http://stackoverflow.com/questions/7084112/css-negation-pseudo-class-not -Per-genitore-antenato-elementi/7084147 # 7084147). L'unico modo per farlo usando ': not' che non si basa sulla natura del markup è usandolo in un modo non standard fornito da jQuery/Sizzle, come indicato in questa risposta. – BoltClock

+0

@BoltClock Funziona bene. Non è solo quello che ti aspetti. – kojiro

2

È possibile farlo utilizzando contesto insieme con selettore come sotto,

$('li', $('div:not(.foo)')) 

LIve Demo

$('li', $('div:not(.foo)')).each(function(){ 
    alert($(this).text()); 
});​ 
+0

+1 - questo evita la stranezza dell'uso di ': not' con un selettore non semplice ed è probabilmente più efficiente rispetto alla ricerca con puro CSS. – kojiro

+1

In realtà, non è più efficiente a meno che non si rimuovano le virgolette interne da ': not()' - averli non è necessario, e non è valido CSS, quindi non sarà più veloce. Vedi http://stackoverflow.com/questions/12475595/why-do-the-not-and-has-selectors-allow-quotated-arguments – BoltClock

+0

Questo fallisce anche se uno degli antenati di 'div.foo' è' div : non (.foo) '. – BoltClock

0

penso che questa soluzione sembra un po 'più bello, ma c'è un po' di polemica sul Commenti API sulle differenze di velocità.

$("li").not(".foo li") 

fiddle

Problemi correlati