2011-11-10 11 views
7

Sto cercando un modo per selezionare elementi che contengono un determinato elemento e quindi filtrare i risultati per ottenere solo il livello più alto. Difficile da spiegare, ma reso più facile con un esempio:jQuery: elementi di livello superiore che contengono x

<div id="one"> 
    <div id="two"> 
     <div id="three" class="find-me"></div> 
    </div> 
</div> 
<div id="four"> 
    <div id="five" class="find-me"></div> 
</div> 

In questo caso, vorrei il mio set di contenere #one e #four. Se provo a fare qualcosa del genere:

var elements = $('div').has('.find-me'); 

Ottengo elementi # uno, # due e # quattro.

Nota: Per 'alto livello' riguarda l'elemento in cima al primo selettore, $('div') in questo caso.

risposta

6

Bene la definizione di ciò che il highest level è, è un po 'ambigua perché, in pratica, se c'è qualche .find-me nella tua pagina il genitore più alto livello sarebbe html tag! che è inutile.

Definendo il problema in modo più specifico, è possibile ottenere una definizione più chiara per questo highest-definition e, ad esempio, dire the farthest div parent et. e per attraversare i genitori di un elemento è possibile utilizzare i metodi .parents() e .closest().

var farthestDiv = $(".find-me").parents("div").last(); 

, ovviamente, se si dispone di più di un occorrenze di find-me è necessario eseguire questo in un ciclo .each().

vedere un esempio qui: http://jsfiddle.net/GsQDb/3/

+0

Buon punto: immagino sia il livello più alto del primo set; '$ ('div')' in questo caso. Mi piace il pensiero di farlo 'indietro' come questo. La velocità è un grosso problema in questa pagina (2 MB di html da attraversare), in modo sarebbe interessato nella differenza di velocità tra questa risposta e la risposta da @karnyj – ajbeaven

0

Se li metti tutti in un unico grande contenitore div, è possibile utilizzare:

$('.container div.find-me').parents($('.container').children()); 

che dovrebbe funzionare, anche se non ho la possibilità di testarlo in questo momento.

Fammi sapere se non ci sono soluzioni più complesse.

1

utilizza il filtro per filtrare gli elementi che non corrispondono a quelli desiderati dopo il primo selettore. esempio:

var elements = $('div.find-me').filter(function(idx){ 
    return !$(this).parents('div.find-me').length; 
}); 
0

È possibile assegnare una classe al maggior numero di div? Se così si può fare qualcosa di simile:

var elements = $("div.topMost").has(".find-me"); 
+0

No, non in questo caso mi dispiace. – ajbeaven

1

Questo farà ciò che si vuole, troverà gli elementi e poi trovare gli elementi più elevati di quelli e di creare un oggetto jQuery degli elementi piu alto.

var elements = $('div.find-me'), highest = []; 

elements.each(function(){ 
var parent = this, body = document.body; 

    while(parent && parent.parentNode !== body) { 
    parent = parent.parentNode; 
    } 

    if($.inArray(parent, highest) < 0) { 
    highest.push(parent); 
    } 
}); 

highest = jQuery(highest); 

jsfiddle:

http://jsfiddle.net/D3jC8/2/

2

Assumendo da "livello superiore", si intende un discendente diretto del tag body, è possibile utilizzare questo uno di linea. Trova tutti gli oggetti con una classe .find-me, quindi cerca nei genitori un tag discendente del tag body (che sarà il livello principale).

$(".find-me").parents("body > *") 

Potete vederlo lavorare qui: http://jsfiddle.net/jfriend00/9LF6u/

Questo ha questi vantaggi:

  1. Qualsiasi tipo di tag può essere il tag di livello superiore (non solo un div)
  2. E ' dovrebbe essere uno dei modi più veloci per farlo dal momento che trova gli oggetti .find-me (che sarà una operazione veloce internamente nella maggior parte dei browser tramite getElementsByClassName) e appena risalita la loro gerarchia genitore.
  3. Gestisce automaticamente i duplicati in modo che un determinato elemento di livello superiore non venga mai elencato più di una volta.
  4. Se si desidera modificare la definizione di livello superiore (ad esempio un oggetto contenitore), è sufficiente modificare il selettore passato al metodo .parents(selector) per riflettere tale modifica.
+0

mia inconsapevolezza di jQuery gestione automatica duplicato è il motivo per cui sono andato con il percorso js regolare la mia risposta: PI arco ai maestri – Esailija

+0

oggetti jQuery creati tramite selettori di filtri non hanno mai duplicati come la maggior parte dei metodi di jQuery finisce con una chiamata interna a '.unique()', che filtra le dups e mette i selettori nell'ordine del documento. – jfriend00

0
$(".find-me").map(function() { 
    return $(this).parents("div").last().get(); 
}); 
Problemi correlati