jQuery mette a disposizione numerosi metodi per muoversi all’interno di un documento effettuando ricerche all’interno di un elemento oppure sfruttando legami di tipo padre-figlio e così via. Abbiamo già visto come sia possibile fare qualcosa del genere mediante alcuni filtri di selezione, in questa lezione vedremo, invece, alcuni metodi specifici offerti dalla libreria.
Sulla base di quanto appreso sino a qui risulta già intuitivo che la selezione di elementi potrebbe essere effettuata semplicemente attraverso i selettori… ma, come già detto, il motto di jquery è "scrivi meno, fai di più", quindi procediamo nel nostro percorso.
Il DOM
Non è questa la sede per spiegare cosa sia il DOM. Si suppone che se state leggendo questa guida già sapete di cosa stiamo parlando. Ad ogni modo è bene ricordare che il DOM può essere rappresentato come un albero rovesciato (dove la radice è la cima) con una molteplicità di ramificazioni. Il documento HTML è la sua radice mentre ogni altro tag in esso incapsulato ne rappresenta una ramificazione.
All’interno di questa struttura ramificata è necessario/utile sapersi muovere e per farlo è possibile fare ricorso a degli strumenti ad hoc che jQuery ci mette a disposizione. In pratica, in questa lezione, vedremo come "navigare" per il DOM partendo da un suo elemento. Vedremo come scendere in profondità (cioè navigare per i rami che dipartono dall’elemento selezionato), risalire verso la radice e come muoverci tra gli altri elementi di pari livello.
Scendere nel DOM
Andare in profondità, muoversi nei meandri del DOM (cioè navigare l’albero verso il basso) è piuttosto semplice con jQuery in quanto ci vengono forniti metodi ad hoc. Vediamoli.
.contents()
Questo metodo consente di accedere a tutti gli elementi figli dell’elemento indicato nel selettore.
Una peculiarità di questo metodo è che può essere applicato ad un iframe contenuto nella pagina per accederne al contenuto. Vediamo un esempio:
<iframe src="testo.html" width="50%" height="400" id="frametesto"></iframe>
<script>
$("#frametesto").contents().find("p").css("color","red");
</script>
Nell’esempio visto sopra estraggo il contenuto dall’iframe (utilizzando il metodo in oggetto) e poi coloro di rosso tutto il testo presente nei paragrafi.
E’ bene precisare, relativamente al funzionamento di questo metodo con gli iframe che l’esempio visto soprà può funzionare esclusivamente con i frame presenti all’interno dello stesso dominio. In base alle regole conosciute come same origin policy; infatti, non abbiamo il "permesso" di accedere lato client al contenuto di un frame remoto.
.find()
Questo metodo (che abbiamo già utilizzato nell’esempio precedente) ci permette di selezionare alcuni elementi contenuti all’interno del nostro selettore. La differenza con il precedente metodo è che questo seleziona gli elementi desiderati in base ad un selettore (o meglio, un’espressione di selezione come quelli utilizzati con la funzione $()), mentre .contents() ritorna tutti i figli dell’elemento su cui è applicato e solo successivamente è possibile effettuare una selezione.
Vediamo un semplice esempio:
$("#intro").find("p").hide();
Con questo codice vengono nascosti tutti i paragrafi presenti all’interno dell’elemento con ID "intro".
Dopo aver visto come si trovano gli elementi interni tramite .find() passiamo ad usare metodi che si basano sulle relazioni gerarchiche tra elementi.
.children()
Come si può intuire dal nome, questo metodo restituisce i figli della selezione su cui è applicato. I figli considerati sono solo quelli immediati; non vengono selezionati gli elementi ulteriormente annidati. Vediamo un semplice esempio: si supponga di avere nella pagina un’indice dei contenuti così strutturato:
<ul id="indice">
<li>Primo capitolo</li>
<li>Secondo capitolo
<ul>
<li>Sottocapitolo</li>
</ul>
</li>
<li>Terzo capitolo</li>
</ul>
Si supponga ora di utilizzare il seguente codice jQuery:
$("#indice").children().css("background-color", "red");
Mediante queste semplici istruzioni viene colorato di rosso lo sfondo dei capitoli, ma non del sottocapitolo perchè non è un figlio diretto dell’elemento individuato nel selettore.
Come per .find(), anche per .children() è possibile passare un selettore come parametro in modo da filtrare la selezione a specifici elementi e non all’universalità degli elementi figli.
Risalire nel DOM
L’albero del DOM può essere navigato anche verso l’alto, a tal fine jQuery fornisce utili metodi. Vediamoli di seguito.
.parent()
Il metodo .parent() assolve alla funzione contraria di .children(), cioè seleziona il genitore dell’elemento considerato. La sintassi è speculare a quella di children().
.parents()
Un metodo simile a parent, ma da non confondere con questo, è parents() (notate la "s" finale). Questo metodo ci permette di attuare un effetto a cascata del metodo parent(), ovvero di selezionare il genitore di un elemento, il genitore di quest’ultimo e così via risalendo nell’albero del DOM fino alla sua radice. Quest’ultimo metodo, utilizzato nomralmente mediante la specifica di un selettore come attributo, consente di individuare in modo semplice eventuali contenitori ulteriori al genitore. Un piccolo esempio aiuterà a chiarirci le idee. Si supponga di avere un codice HTML del genere:
<ul class="livello-1">
<li class="item-a">A</li>
<li class="item-b">B
<ul class="livello-2">
<li class="item-x">X</li>
<li class="item-y">Y</li>
<li class="item-z">Z</li>
</ul>
</li>
<li class="item-c">C</li>
</ul>
Ora si inserisca nella pagina questo codice jQuery:
$("li.item-x").parents("li").css("background-color", "red");
Con questo codice verranno colorati di rosso tutti gli elementi (<li>) dell’elenco puntato cui appartiene l’elemento indicato nel selettore.
.closest()
E’ un metodo simile a .parents() ad esclusione del fatto che, a differenza di quest’ultimo, parte dall’elemento corrente e restituisce sempre un solo elemento (qualora l’espressione consenta di selezionarne più di uno, restituirà solo quello "più vicino").
Spostarsi all’interno dello stesso livello del DOM
Anche in questo caso jQuery ha diversi metodi ad hoc. Vediamoli.
.next(), .nextAll(), .prev(), .prevAll()
Questi metodi servono per selezionare gli elementi successivi e precedenti a quello selezionato.
Il primo metodo (.next()) seleziona solamente l’elemento immediatamente successivo all’interno dello stesso livello gerarchico; il secondo metodo (.nextAll()) invece seleziona tutti i successivi elementi, sempre all’interno dello stesso livello.
Specularmente, i metodi .prev() e .prevAll(), svolgono rispettivamente il compito di selezionare l’elemento precedente e tutti gli elementi precenti.
Per chiarirci meglio le idee vediamo un esempio di utilizzo del metodo .next() (l’esempio vale anche per gli altri metodi indicati). Si supponga di avere il seguente elenco puntato:
<ul>
<li>elemento 1</li>
<li>elemento 2</li>
<li class="corrente">elemento 3</li>
<li>elemento 4</li>
<li>elemento 5</li>
</ul>
Ora si inserisca nella pagina questo codice jQuery:
$("li.corrente").next().css("background-color", "red");
Mediante questo codice verrà colorato di rosso l’elemento successivo a quello con classe "corrente", cioè l’elemento n.4 della lista. Se avessimo utilizzato il metodo nextAll() si sarebbe colorato anche l’elemento n.5 della lista. Ovviamente avremmo ottenuto risultati speculari se avessimo utilizzato, rispettivamente, .prev() e .prevAll().
.siblings()
Questo metodo è complementare a quelli visti poco sopra in quanto ritorna tutti gli elementi dello stesso livello di quello preso in considerazione ad esclusione dell’elemento corrente. Vediamo un esempio: si prenda il medesimo elenco puntato visto per .next(). Dopodichè si inserisca nella pagina questo codice jQuery:
$("li.corrente").siblings().css("background-color", "red");
Mediante queste istruzioni verrano colorati di rosso tutti gli elementi dello stesso livello (cioè tutti gli elementi della lista) ad eccezione dell’elemento con classe "corrente".