Share |

domenica 24 gennaio 2010

Javascript: Traversing the D.O.M.

Molto spesso, soprattutto in fase di debug, mi e' comodo poter visualizzare in un documento HTML il risultato di una chiamata AJAX ad una risorsa XML e quindi mi sono attrezzato creando una funzione JavaScript che ricevuto un DOM-Object, tramite il metodo responseXML della classe JavaScript XMLHttpRequest, lo naviga ricorsivamente nodo per nodo, passando per ogni nodo figlio.

La classe XMLHttpRequest e' il cuore del framework AJAX, che sta per Asyncronus JavaScript And XML, ovvero il padre della nuova frontiera dei servizi Web: il famoso Web2.0.

Il compito della funzione javascript che porto come esempio e' di attraversare un D.O.M. object partendo da qualsiasi nodo del documento, che sia la radice (root) o un nodo figlio (childNode).
Ad ogni childNode che incontra la funzione verifica se questo nodo possiede a sua volta altri figli, e quindi rappresenta un ramo dell'albero XML, oppure se e' solo una foglia.
Nel primo caso, la funzione si richiama da se per scorrere ricorsivamente il nuovo ramo fino ad incontrare una foglia, altrimenti, terminata la lista di childNode, continua nell'analisi del nodo successivo.

Il funzionamento dello script javascript e' stato testato con esito positivo sui due browser piu' famosi: Mozilla FireFox ed Internet Explorer 6 e 7.

Se qualcuno di voi avesse testato lo script con altri prodotti potrebbe gentilmente postare un commento all'articolo.

Passiamo quindi ad analizzare il prototipo della funzione:

function walkXmlTree(xmlelement, htmlelement, cssFatherTagName
                      , cssChildTagName, cssTagData);

Dunque la funzione javascript walkXmlTree riceve 5 parametri:

  • xmlelement: l'elemento XML radice da cui iniziare a scorrere il DOM XML
  • htmlelement: un oggetto HTML nel quale appendere il contenuto del DOM XML (solitamente un DIV)
  • cssFatherTagName: classe CSS per decorare i nodi Padre XML (ParentNode)
  • cssChildTagName: classe CSS per decorare i nodi Figlio XML (childNode)
  • cssTagData: classe CSS per decorare i nodi testo (foglie) XML (textNode)

E' ora il momento di passare all'analisi del codice sorgente dell'esempio: come al solito lo spiattello lì, e come sempre sono ben commentati ogni passaggio critico ed ogni punto chiave del codice sorgente.

Buona Visione.

function walkXmlTree(xmlelement, htmlelement 
    ,cssFatherTagName, cssChildTagName, cssTagData){

  var obj = xmlelement;
  var elem = htmlelement;

  //Se cssFatherTagName e' null lo inizializzo con '' 
  var cssFather = (cssFatherTagName != null) ? cssFatherTagName : '';
  var cssChild = (cssChildTagName != null) ? cssChildTagName : '';
  var cssData = (cssTagData != null) ? cssTagData : '';

  //Scorro tutti i childNodes del nodo in analisi 
  for(var i=0;i<obj.childNodes.length;i++){
    var child = obj.childNodes[i]; 

    /**
     * Se è un nodo di Tipo ELEMENT_NODE ed ha Figli 
     * ne prendo il valore, ricordo che il valore di un nodo 
     * è trattato come figlio e precisamente è un TEXT_NODE
     */
    if(child.nodeType == 1 && child.childNodes != null 
        && child.childNodes.length > 0){
      if(child.childNodes.length == 1){
        /**
         * In assenza di attributi (ATTRIBUTE_NODE) 
         * il valore testo di un nodo e' sempre il primo figlio
         * e lo si preleva accedendo alla sua proprietà 'data' 
         */ 
         if(child.firstChild.data != null 
            && child.firstChild.data != undefined){
          /**
           * La proprietà innerHTML mi garantisce la massima 
           * compatibilità con tutti i tipi di browser
           */
          elem.innerHTML += '<span class="' + cssChild + '">'
              + child.tagName + '</span>: '
              + '<span class="' + cssData + '">'
              + child.firstChild.data + '</span><br>';
         }
      }  
      /**
       * Nel caso il nodo in esame abbia piu' di un figlio
       * richiamo ricorsivamente walkXmlTree passandogli il
       * suddetto nodo Padre.
       */
      else{
        elem.innerHTML += '<br><span class="' + cssFather 
            + '">' + child.tagName + '</span>:<br>';
        walkXmlTree(child,elem,cssFather,cssChild,cssData);
      }
    }
  } 
}

Il tutto e' molto trasparente, non c'è un granchè da aggiungere.
Se avete scoperto di avere delle lacune sul DOM Object potete dare un occhio alla più autorevole fonte di standard per il WEB: il consorzio W3C.

Alla prossima,
MA.

0 commenti:

Posta un commento

Non ti è chiaro qualcosa?
No problem, posta il tuo dubbio ;)

..... e ricordati di firmarlo!