selezionando l'elemento radice in jquery
-
22-07-2019 - |
Domanda
Devo essere in grado di selezionare l'elemento radice da un frammento senza conoscere i tipi di nodo, la classe, l'id o la gerarchia.
<div id="0">
<div id="0a">
<div id="a01"></div>
</div>
<div id="0b">
</div>
<div id="0c">
</div>
</div>
Voglio essere in grado di fare qualcosa come $ (': root') e ho selezionato 0 nell'esempio sopra.
Meglio ancora preferirei $ (': level (0)')
che significherebbe lo stesso di cui sopra, $ (': level (1)')
selezionerebbe 0a, 0b e 0c e $ (': level (1) > div')
selezionerebbe a01.
Qualche idea su come farlo in modo ordinato?
Soluzione
Mentre a questa domanda è stata data una risposta perfettamente corretta un po 'di tempo fa, stavo solo cercando di provarci da solo e non ero troppo entusiasta di usare un selettore come *: not (* *)
- principalmente a causa delle probabili spese generali. Non so se questa è una recente aggiunta all'abilità di jQuery (sto usando 1.8) ma puoi usare:
$(':eq(0)');
Questo selezionerà il primo elemento non textnode trovato, quindi a meno che il dom che stai attraversando non sia illegale nella sua formazione, dovresti sempre ottenere l'elemento root. È anche altamente ottimale perché jQuery dovrebbe sapere di fermarsi dopo il primo elemento trovato.
Quindi ecco qualcosa per tutti quei fan dei WSOD là fuori:
$(':eq(0)').remove();
Oh, e nel caso in cui non sia ovvio che i frammenti di codice sopra riportati stessero solo illustrando il selettore, e ti ritrovi a lavorare con un frammento parziale (piuttosto che con il documento completo), quindi dovresti usare questo selettore con il filtro di jQuery metodo:
$(fragment).filter(':eq(0)');
Tuttavia, quando lavori con i frammenti puoi semplicemente fare quanto segue:
$(fragment).get(0);
Anche se tieni presente che .get (0)
può selezionare nodi di testo / commento se sono il primo elemento nel tuo documento, mentre l'approccio del filtro troverà sempre il primo elemento effettivo.
Altri suggerimenti
OK, quindi quello che devi fare è il seguente (presumendo che tu stia usando l'esempio che hai), se vuoi trovare il nodo di livello superiore usando jquery è il seguente:
$('*:not(* *)');
Ciò che stai letteralmente chiedendo qui è per tutti i nodi che non sono figli di altri nodi. Il problema è che per un documento HTML, questo ti darà sempre solo l'elemento HTML, che non è particolarmente utile. Quindi, se vuoi trovare l'elemento di primo livello nel corpo di un documento html, useresti qualcosa di molto più semplice:
$('body > *');
se poi volessi il secondo livello, andresti semplicemente
$('body > * > *');
Ma, supponendo che tu abbia una sorta di struttura di documento arbitraria (come quella di cui parli), quello che puoi fare è usare il primo esempio per trovare il primo livello:
$('*:not(* *)');
e poi per il secondo livello
$('*:not(* *)').find('> *');
e per il terzo livello
$('*:not(* *)').find('> * > *');
e così via e così via. Se stai cercando un elemento div radice (supponendo che il tuo campione sia come la domanda), puoi farlo:
$('div:not(div div)');
e così via, sostituendo * con div. Non sono sicuro del motivo per cui vorresti farlo, ma funzionerà. Il problema è che la domanda in realtà non fornisce abbastanza contesto per consentirci di offrirti un'alternativa migliore.
Sono più un tipo Prototipo, ma penso che potresti ottenere tutti i nodi quindi ottenere il primo nodo nella matrice:
$('*')[0]
Quindi ottieni gli elementi figlio (per 0a, 0b e 0c)
$('*')[0].children()
Se hai i tuoi elementi come frammento jQuery come:
var myElements = $('<div id="0">
<div id="0a">
<div id="a01"></div>
</div>
<div id="0b">
</div>
<div id="0c">
</div>
</div>');
allora puoi trovare il primo elemento:
myElements.filter(":first")
La funzione filtro guarda dall'elemento radice del frammento.
jQuery non è necessario ...
var root = document.firstChild;
Potrei fraintendere la domanda, ma supponendo per radice intendi il punto in cui il genitore è un tag diverso dal figlio, allora dovrebbe funzionare quanto segue.
function GetRoot(element) {
while(element.parent().attr("tagName") == element.attr("tagName")) {
element = element.parent();
}
return element;
}
Questo in pratica cammina sull'albero fino a quando non trova un genitore che è un tag diverso e quindi restituisce l'elemento. Per il tuo esempio ciò significherebbe che se il tuo elemento fosse in un, o qualunque cosa lo rilevi come root e lo restituisca.
Anche creare un selettore jquery personalizzato con questo dovrebbe essere possibile, ma ovviamente è più complicato.
Dovrebbe anche essere abbastanza facile estenderlo per prendere un numero intero che definisce il livello. Tutto quello che dovresti fare è camminare lungo l'albero fino alla profondità specificata una volta trovata la radice e restituire quegli elementi.
puoi esaminare usando le funzioni parent () e children (). se devi passare su più livelli, puoi incatenarli in questo modo.
$("#a01").parent().parent() //returns <div id="0">
vedi il mio commento e proverò a dare una soluzione migliore.
Ricevo frammento html dalla chiamata ajax e ho anche bisogno di ottenere il div root da esso. Quello che ho fatto è stato semplicemente chiamare $ (data)
, e jQuery analizzerà il testo di ritorno come HTML e ti darà il root.
$.ajax path,
type: 'GET'
contentType: 'application/x-www-form-urlencoded;charset=UTF-8'
success: (data) ->
$(data)
Se vuoi selezionare il genitore di livello superiore di un elemento ma ancora sotto il corpo, andrei
$(obj).parents().filter('body > *')