Il logo del sito

Appunti su JavaScript

JavaScript e DOM

DOM

Le pagine web, scritte in html sono documenti che aderiscono allo standard HTML DOM (Document Object Model).

Un documento html è visto come un insieme di oggetti, coincidenti con gli elementi html presenti nel documento stesso, organizzati gerarchicamente in un albero il cui elemento radice è <html> e le cui foglie sono i valori degli attributi degli elementi.

JavaScript è un linguaggio di programmazione orientato agli oggetti che, fra le altre funzioni, consente di:

Per utilizzare bene JavaScript bisogna conoscere lo standard DOM.

Allo standard DOM possono aderire diversi tipi di documenti fra cui i documenti html.

Lo standard HTML DOM definisce gli elementi html (tag html) come oggetti dotati di proprietà,(attributi html), e metodi.

L'oggetto document

L'elenco che segue è riportato nel documento w3schools js_htmldom

Dal punto di vista formale questo documento mi lascia un po perplesso, ma il suo studio consente un approccio sicuramente pragmatico alla programmazione js dom.

La pagina web per DOM è un oggetto di nome document. DOM rende disponibile a JavaScript l'oggetto document ed i seguenti metodi raggruppati per categoria:

Prova dei metodi.

Il codice JavaScript è inserito in un file con estensione js, js_01.js, il cui contenuto è mostrato nella sezione adiacente.

La prima parte dello script associa ad ognuno dei pulsanti test_xx un event handler, una funzione che viene eseguita in risposta all'evento click operato sul pulsante stesso. I pulsanti sono in realtà pagragrafi <p class="pulsante" id="testx"> e per renderle "reattive" occorre aver specificato per esse la proprietà di stile cursor:pointer;

Ecco le proprieta css dei "pulsanti".


.pulsante{
   cursor:pointer;
   border:1px solid;
   border-radius:10px;
   text-align:center;
   width:50%;
   background:lime;
}           

Notare come il nome degli oggetti debba essere diverso dal nome dell'event handler. Inizialmente, avevo scritto:test1.addEventListener('click', test1); perdendo poi del tempo per capire perchè la funzione test1 non funzionava.

1. Metodi che restituiscono elementi html o array di elementi html.

1.1 document.getElementById('id')

La funzione restituisce l'elemento html il cui identificatore è 'test1'.

test_01

In alternativa a var et1 = document.getElementById('test1') si può usare var et1 = document.querySelector('#test1'). Le due funzioni restituiscono lo stesso oggetto ma mentre il prima usa i riferimenti html il secondo usa i riferimenti css.

1.2 document.getElementsByTagName('tagName')

La funzione restituisce tutti gli elementi <h2> presenti nel file html e ne visualizza il contenuto. in un alert box.

test_02

Analogamente alla funzione precedente esiste il metodo document.querySelectorAll('tagName') che restituisce lo stesso insieme di oggetti utilizzando i riferimenti css.




1.3 document.getElementsByClassName('className')

La funzione restituisce tutti gli elementi di classe "pulsante" presenti nel file html e ne visualizza il contenuto. in un alert box.

test_03

Lo stesso risultato si può ottenere con document.querySelectorAll('.className') che restituisce lo stesso insieme di oggetti utilizzando ii riferimenti css.



2. Metodi che modificano elementi html.

2.1 element.innerHTML = contenuto

La funzione modifica il contenuto del paragrafo che ha come contenuto testuale la stringa: PARAGRAFO DA CAMBIARE

test_04

Notare che per estrarre il contenuto testuale del paragrafo ottenuto con var el=document.getElementById('pDaModificare') ho utilizzato: el.textContent

PARAGRAFO DA CAMBIARE



2.2 element.attributo = valore

A proposito di correttezza formale:

Credo di aver già provato questa funzione nell'esempio precedente quando ho testato il contenuto dell'elemento el con el.textContent == "PARAGRAFO DA CAMBIARE"

Nello standard w3c HTML 5.2 si possono trovare tutti gli attributi di ogni elemento html. Così decido di provare a modificare l'attributo hidden di un paragrafo appositamente predisposto.

test_05

La funzione modifica il valore dell'attributo hidden del seguente paragrafo:

NASCONDIMI

2.3 element.setAttribute(attributo, valore)

Mi sembra equivalente al "metodo" precedente.

test_06

Esegue l'identica funzione di test_05 con il metodo setAttribute.

3. Metodi per aggiungere ed eliminare elementi

3.1 document.createElement(element)

Uso questo metodo per creare un nuovo paragrafo, ma dopo averlo creato ancora non ho capito cosa farne. Probabilmente per farci qualcosa di utile sarà necessario passare l'elemento creato a qualche altro metodo.

test_07

Per il momento mi fermo qui. Ci tornerò in seguito, quando avrò capito come fare ad inserire l'elemento creato nella posizione del documento da me prestabilita. Vedi test_09.

3.2 document.removeChild(element)

Considerato il nome del metodo, a prima vista pensavo fosse banale eliminare un elemento dal documento. Così ho pensato di creare un paragrafo "etichetta da rimuovere" e scrivere una funzioncina che utilizzasse il metodo removeChild per eseguire il compito.

In realtà mi mancavano un po di conoscenze.

test08() fa il lavoro che mi ero proposto, ed i tentativi che ho fatto per arrivarci mi hanno fatto capire qualcosa in più su DOM. Non sono affatto sicuro che questa sia la via migliore, ne sarei sorpreso.

Nella funzione ho lasciato qualche traccia delle prove che ho fatto.

test_08

Paragrafo da rimuovere



















3.3 document.appendChild(element)

Ora che ho capito come accedere ai "figli" dovrei essere in grado di creare un nuovo paragrafo ed appenderlo in fondo a questa sezione (Prova dei metodi).

test_09

Ogni volta che clicchi su test_09 il nuovo paragrafo viene appeso in fondo alla pagina.







Codice JavaScript

Quando la pagina viene caricata ecco le istruzioni JavaScript che inizializzano gli event handler sugli elementi testxx.


var test1 = document.getElementById('test1');
var test2 = document.querySelector('#test2');
var test3 = document.querySelector('#test3');
var test4 = document.querySelector('#test4');
var test5 = document.querySelector('#test5');
var test6 = document.querySelector('#test6');
var test7 = document.querySelector('#test7');
var test8 = document.querySelector('#test8');
var test9 = document.querySelector('#test9');

test1.addEventListener('click',test01);
test2.addEventListener('click',test02);
test3.addEventListener('click',test03);
test4.addEventListener('click',test04);
test5.addEventListener('click',test05);
test6.addEventListener('click',test06);
test7.addEventListener('click',test07);
test8.addEventListener('click',test08);
test9.addEventListener('click',test09);







function test01(){ 
/* Prova del metodo: 
*  element document.getElementById(String);
*  Con String = 'test1' l'elemento restituito è quello contenente l'etichetta test_01 stessa.*/
   var el = document.getElementById('test1'); 
/*   var el = document.querySelector('#test1');  fornisce lo stesso risultato */ 
   alert('function test01(): elemento cliccato: ' + el.innerHTML);
   return;
}


function test02(){  
/* Prova del metodo: 
*  element[] document.getElementsByTagName(String);
*  Con String = 'h2' restituisce un array di oggetti consistente di tutti gli elementi html con tag <h2>.*/  
   var el = document.getElementsByTagName('h2'); 
/* var el = document.querySelectorAll('h2'); fornisce lo stesso risultato.*/  
   alert('function test02(): la pagina contiene ' + el.length + 
         ' elementi con tag h2:');
   for(var i=0; i< el.length; i++){
      alert(el[i].innerHTML);
   }
   return;
}


function test03(){ 
/* Prova del metodo: 
*  element[] document.getElementsByClassName(String);
*  Con String = 'pulsante' restituisce un array di oggetti consistente di tutti gli elementi html 
*  con class="pulsante"*/  
   var el = document.getElementsByClassName('pulsante');
/*   var el = document.querySelectorAll('.pulsante'); fornisce lo stesso risultato.*/     
   alert('function test03(): la pagina contiene '+ el.length + 
         ' elementi con classe  pulsante:');
   for(var i=0; i< el.length; i++){
      alert (el[i].innerHTML);
   }
   return;

   
   
   
   
function test04(){
/* Prova del metodo: 
   String element.innerHTML=String;*/
   var el=document.getElementById('pDaModificare');
   if (el.textContent == "PARAGRAFO DA CAMBIARE"){
      el.innerHTML="<mark>PARAGRAFO MODIFICATO</mark>";
   }else{
      el.innerHTML="<mark>PARAGRAFO DA CAMBIARE</mark>";
   }
   return;
}



function test05(){
   /* Prova del metodo: 
   contenuto element.attributo=contenuto;*/
   var el=document.getElementById('pHidden');
   if (el.hidden == false){
      el.hidden=true;
   }else{
      el.hidden=false;
   }
   return;
}












function test06(){
   /* Prova del metodo: 
    element.setAttribute('attributo', valore);*/
   var el=document.getElementById('pHidden');
   if (el.hidden == false){
      el.setAttribute('hidden', true);
   }else{
      el.hidden=false;
      /* el.setAttribute('hidden', false);
         non fa quello che mi aspetto, o non ho capito come funziona hidden, o 
         non ho capito come funzione setAttribute(attributo, valore). ci ritornerò
         se e quando avrò capito dove è il problema.*/
   }
   return;
}
 
 
 
 
function test07(){
   /* Prova del metodo: 
   document.createElement(element);*/
   var nuovoParagrafo=document.createElement('p');
   nuovoParagrafo.innerHTML = '<mark>pippo</mark>';
   alert ('NuovoParagrafo ' + nuovoParagrafo.innerHTML + ' creato.');
   return;
}





function test08(){
   /* Prova del metodo: 
   void document.removeChild(element);*/  
   var parametro = 'view'
   var el = document.getElementsByClassName(parametro);
   /* getElementsByClassName('className') restituisce un array di elementi, ma cosa c'è in questi elementi?
   C'è il codice html racchiuso negli elementi contrassegnati con class='className'.
   Nel documento in oggetto c'e nè uno solo.*/    
   alert('Esploro il contenuto di ' + parametro);
      for (var i=0; i<el.length; i++){
         alert ('el['+ i + ']: ' + el[i].innerHTML);
      }
   /* Il paragrafo che voglio rimuovere si trova in el[0]. Questo l'ho capito dal pezzetto di codice precedente. 
   allora lo cancellerò con:
   el[0].removeChild(document.getElementById('test_08'));
   ma non funziona. Dagli esempi di utilizzo trovati nel web, ho capito che gli oggetti elements hanno una
   proprietà children consistente nel array di elementi html che contencono. Il paragrafo che voglio 
   eliminare è nell'array el[0].children[]. Ma in quale posizione è ? Lo stabilisco con il pezzetto 
   di codice seguente:*/  
   alert('el[0].children.length ' + el[0].children.length );
   var k=-1;
   for(var i=0; i< el[0].children.length; i++){
      if (el[0].children[i].textContent == 
         document.getElementById('test_08').textContent){
         k=i;
         alert('found ' + i);
      }else{/*alert (el.children[i].textContent);*/} 
   } 
   /* Se all'uscita del loop precedente, k è diverso da -1, significa che ho trovato il paragrafo
   che voglio rimuovere e che questo  si trova all'indice k del array el[0].children[]. Ora posso rimuoverlo*/
   if (k!=-1){
      el[0].removeChild(el[0].children[k]);
   }else{
      alert('Elemento: '+ document.getElementById('test_08') + ' non trovato' );
   }   
   return;
}


function test09(){
   /* Prova del metodo: 
    * void document.appendChild(element);
   *
   * 1 - Creo un nuovo paragrafo con document.createElement;
   * 2 - Aggiungo la proprietà id al paragrafo creato con element.setAttribute;
   * 3 - Ottengo l'elemento padre a cui appendere il nuovo paragrafo con
   *     document.getElementsByClassName;
   * 4 - appendo il nuovo paragrafo all'elemento padre.
   */   
   var nuovoParagrafo=document.createElement('p');
   nuovoParagrafo.innerHTML = '<mark>pippo</mark>';
   nuovoParagrafo.setAttribute('id',"pippo");
   var padre=document.getElementsByClassName('view');
   padre[0].appendChild(nuovoParagrafo);
   alert ('Il nuovo paragrafo è stato inserito in fondo alla pagina');
   return;
}