Javascript non intrusivo (3/6)

Terzo capitolo del corso di javascript non intrusivo. Primo, pulire il codice. Secondo, accedere agli elementi. Terzo: creare, distruggere e modificare elementi.

Capitolo 3: Creare e distruggere contenuto

La maggiore forza del DOM è la possibilità non solo di leggere, ma anche di alterare il contenuto e la struttura di un documento. Per questo abbiamo diversi metodi a nostra disposizione.

Creare nuovo contenuto

createElement(element)
crea un nuovo elemento

createTextNode(string)
crea un nuovo nodo di testo con valore string

I nuovi elementi creati non sono aggiunti al documento immediatamente, ma restano nel limbo finchè non verranno inseriti da qualche parte nell’albero dei nodi. Queste funzioni sono da applicare al document object piuttosto che a un nodo.

Javascript:

Alterare il contenuto esistente

setAttribute(attribute,value)
aggiunge un nuovo attributo con valore value all’oggetto.

appendChild(child)
aggiunge child come childNode all’oggetto object.
child deve essere un oggetto, non può essere una stringa.

cloneNode()
copia l’intero nodo con tutti i childNodes.

hasChildNodes()
controlla se l’oggetto possiede childNodes, restituendo true in caso affermativo.

insertBefore(newchild,oldchild)
aggiunge newchild prima di oldchild all’albero del documento.

removeChild(oldchild)
rimuove il childnode oldchild.

replaceChild(newchild, oldchild)
sostituisce oldchild con newchild.

removeAttribute(attribute)
rimuove l’attributo attribute dall’oggetto.

Esempio: immagini

Immaginiamo di avere collegamenti a delle immagini, e che questi collegamenti debbano aprirsi in una nuova finestra nei browser senza Javascript, o sotto il link quando Javascript è disponibile.

HTML:

Ora, quando Javascript e il DOM sono disponibili, noi vogliamo:
- Eliminare il testo “(new window)” dai collegamenti
- Aggiungere un gestore di eventi per chiamare la funzione popw()

Questa funzione dovrebbe
- Mostrare l’immagine collegata sotto il collegamento, nel caso non sia già visibile.
- Rimuovere l’immagine, se già presente (per evitare che il collegamento aggiunga immagini più volte).
- Far scomparire l’immagine quando l’utente esegue un click sopra di essa

Il primo problema non è difficile da risolvere:

Javascript:

Ora, per la funzione popw() abbiamo bisogno di usare alcuni dei metodi elencati prima:

Javascript:

Guarda questo esempio in azione

Esempio: scelta delle date

Diciamo di avere per esempio un modulo che contenga campi con date e la nostra intenzione sia di offrire agli utenti con Javascript abilitato un calendario, mentre gli altri semplicemente dovranno inserire la data manualmente. Non discutiamo ora la funzione calendario, ma concentriamoci su come invocarla.

Iniziamo con il necessario codice HTML. Per vedere quali elementi debbano avere un link al calendario, aggiungiamo classi con il nome date ad esse.

HTML

Eseguiremo quindi un ciclo attraverso tutti i tag input nel document, e controlleremo quale tra questi avrà un className che contenga date (ricordate, elementi possono avere più classi all’interno dell’attributo classe!)

Nel caso sia il tag ricercato, dovremo creare un nuovo collegamento, e il testo del collegamento stesso. Aggiungeremo il testo come elemento figlio del collegamento, e aggiungeremo un gestore di eventi per invocare il nostro script calendario.

Una volta creato il collegamento, lo aggiungeremo dopo il campo input corrispondente.

Javascript:

Guarda questo esempio in azione

Ora tutti i campi con date hanno un link dopo di essi che punta a picker(). Ciò di cui abbiamo bisogno ora è di dire alla funzione di scelta dove applicare il valore che restituirà.

Dal momento che inviamo il collegamento stesso come oggetto a picker(), dobbiamo accedere l’elemento adiacente più vicino, INPUT

Javascript:

Siamo vicini, ma non abbastanza. Siccome abbiamo aggiunto il nuovo collegamento come ultimo figlio del nodo principale dell’input, è molto probabile che il previousSibling del nostro nuovo collegamento non sia INPUT ma lo spazio vuoto! Quindi, abbiamo bisogno di effettuare un ciclo attraverso gli elementi adiacenti precedenti finchè non identifichiamo un elemento.

Javascript:

Effettuare cicli è sempre complicato e può essere molto lento. Per evitare il ciclo abbiamo bisogno di modificare la nostra funzione.

Modificare la funzione addPickerLink()

E’ sempre facile usare appendChild(), ma ci rende dipendenti dal markup. Cosa accadrebbe per esempio nel caso in cui si debba aggiungere uno SPAN con un asterisco vicino all’elemento input per indicare un campo obbligatorio, in un secondo tempo?

Il trucco è quello di usare insertBefore() sul nextSibling del nostro campo input.

Javascript:

Guarda questo esempio - corretto - in azione

Cose da ricordare

Questo è quanto, con questi strumenti siamo in grado di avere accesso e modificare ogni elemento di un documento, e possiamo migliorare l’esperienza utente senza diventare dipendenti da Javascript.

Può creare un po’ di confusione all’inizio, ma una volta che la vostra mente girerà un minimo attorno al DOM, sembrerà sempre più facile ogni volta che lo userete.

Alcuni ostacoli comuni sono:

- Assicurarsi di controllare un elemento prima di accedervi. Molti browsers sono contenti di fare un controllo per object.nextSibling.nodeName e restituiscono false quando non è presente un elemento successivo adiacente o se è un nodo testuale, mentre altri restituiscono un errore affermando che state tentando di accedere un attributo di un elemento non esistente.

- Siate certi di non affidarvi troppo al markup, in quanto le interruzioni di linea possono essere lette come nodi, o il markup può cambiare, e voi non avete (non dovreste avere; N.d.T) voglia di modificare il vostro script ogni volta che il markup viene modificato.

- E’ possibile leggere il contenuto di un elemento leggendo i valori dei suoi childNodes, non il valore dell’elemento stesso!
document.getElementsByTagName(’h2′)[0].nodeValue è vuoto,
document.getElementsByTagName(’h2′)[0].firstChild.nodeValue non lo è.

- Quando fate un controllo per nodeNames e attributes, siate certi di restare case insensitive, in quanto alcuni browsers rendono gli elementi in maiuscolo, mentre altri in minuscolo.

- Il codice HTML generato via DOM nella maggior parte dei casi non è perfettamente formato; se intendete riutilizzare il codice HTML di una pagina generata via browser, dovrete pulire il codice.

- Evitate di esagerare con i cicli, se avete la possibilità di creare il markup necessario al vostro lavoro, usate preferibilmente gli ID.

- Conoscete la vostra sintassi. Molto spesso un getElementsById può causare molte riscritture.

- Conoscete i vostri oggetti Javascript e attributi HTML, in quanto non è utile fare controlli per un attributo che non è inteso essere il vostro punto di partenza.

- Non pensate che il vostro personale modo di scrivere codice sia quello usato più comunemente. Un esempio è quello di controllare se className contenga al suo interno la vostra stringa piuttosto che SIA la vostra stringa, dal momento che molti sviluppatori usano spesso classi multiple.

E a proposito di innerHTML?

Quando venne rilasciato Internet Explorer 4, naque innerHTML, un via rapida per generare e modificare contenuto. E’ un modo per leggere il contenuto di un elemento molto più facilmente rispetto alle raccomandazioni W3C originali. Per fare un esempio specifico, se un elemento contiene childNodes che sono essi stessi elementi e la nostra intenzione è quella di leggere l’intero contenuto. Per fare questo esclusivamente tramite il DOM, è necessario effettuare esercizi complessi per controllare ogni nodeTypes e leggere il valore di ogni nodo.

innerHTML è molto più semplice da usare, ma ha alcuni svantaggi. Per esempio non avete alcuna informazione sugli elementi creati tramite di esso in quanto l’intero valore è una stringa piuttosto che un oggetto. Inoltre, innerHTML è legato esclusivamente al linguaggio HTML, non alla famiglia XML, e DOM è inteso attraversare ogni markup.

Per una tabella di confronto e informazioni sul supporto dei browsers potete leggere la sezione DOM di Quirksmode.org o la grande discussione su Developer-x.

http://www.onlinetools.org/articles/unobtrusivejavascript/chapter3.html

2 commenti

  1. simone
    Pubblicato 06/04 alle 14:16 | Permalink

    Ciao, nel caso in cui volessi gestire un menu a tendina:

    ….

    Come mi devo comportare??

  2. pixline
    Pubblicato 09/04 alle 9:42 | Permalink

    se ho capito bene cerchi una cosa simile a http://www.onlinetools.org/tools/yadm/ , che è uno dei nostri preferiti, oltre ad essere creato dall’autore del corso che stai commentando.

    il mio consiglio comunque è quello di imparare a cercare le cose su google, prima di fare domande in questo modo… se provi http://www.google.com/search?q=javascript+drop+down+menu noterai qualcosa come 85 *milioni* di risposte, molte più di quelle che possiamo dare noi o altri blog.

web counter