Pagine

lunedì 21 marzo 2016

Programmazione web lato client (4 parte a)

Per gli studenti della Ia e Ib Itis Volta Frosinone: questa volta vi lancio in acque profonde!

Al solito, per comodità, dal momento che l'interfaccia del programma non occupa molto spazio sullo schermo, l'ho inserito anche in questa pagina utilizzando un tag "iframe".


Il programma crea, premendo il tasto "Tabellina", una tabella pitagorica di 15 righe e 15 colonne. Il tasto "Clear" la cancella. Nulla di sensazionale, ma è un pretesto per insegnarvi il DOM.

Il DOM (Document Object Model) viene creato dal browser quando la pagina html viene caricata. Potete pensare al DOM come a uno schema della pagina, costruito dal browser mentre la carica. In pratica il browser "prende appunti" e memorizza al suo interno uno schema in cui ogni tag è rappresentato da un pallino (nodo), e i tag che si trovano al suo interno sono altri nodi che vengono chiamati "childnodes" (nodi-figlio). Per capirci, prendiamo in esame la pagina html dell'esempio, che riporto qui sotto:

<!DOCTYPE html>
<html>

   <head>
      <link href="cssDoc.css" rel="stylesheet" type="text/css" />
      <script language="javascript" src="jsDoc.js"></script>
   </head>
  <body>
    <button onclick="document.getElementById('demo').appendChild(makeTable(15,15))">Tabellina</button>
    <button onclick="deleteTable()">Clear</button>
    <p align="center" id="demo"></p>
  </body>
</html>


 Lo schema di questa semplicissima pagina è il seguente (a parte la dichiarazione di tipo <!DOCTYPE html>.



Il nodo <html> ha due figli (childNodes): <head> e <body>. A loro volta <head> e <body> hanno rispettivamente 2 (<link> e <script>) e 3 (<button>, <button> e <p>) childNodes. Questo schema, ovviamente memorizzato in formato digitale, è il DOM della pagina.

Per la cronaca, ma ne parleremo più diffusamente in un altro post, osserviamo che ogni nodo (node) può avere degli "attributi". Ad esempio, il nodo <p> ha l'attributo "id", il cui valore è in questo caso "demo".

 I programmatori dei browsers, oltre a fornire la capacità di creare uno schema della pagina, rendono disponibili un set di metodi per manipolare i nodi. Ad esempio, se un nodo ha un attributo "id" (poniamo con il valore "demo") noi possiamo individuarlo (cioè ottenere un riferimento ad essso) e memorizzare tale riferimento in una variabile (se questo ci fa comodo) con l'istruzione:

var x = document.getElementById("demo");

Ora vi presenterò, e spiegherò, alcuni metodi che ho usato per realizzare il programmino oggetto del nostro studio.
  • var tbl= document.createElement("table"); //crea un tag <table>
  • var row= document.createElement("tr");    //crea un tag <tr>
  • var col= document.createElement("td");    //crea un tag <td>
Il metodo createElement("tag") crea un nodo del tipo specificato in "tag". Nel nostro caso, rispettivamente un nodo "table", un nodo "tr" e un nodo "td".

Si noti che il metodo createElement("tag") appartiene all'oggetto document. In altre parole, non posso scrivere solo createElement("tag"), ma devo necessariamente scrivere document.createElement("tag"). Il che significa: crea l'oggetto (il nodo) "tag" utilizzando il metodo createElement("tag") dell'oggetto (nodo) "document".

InZomma: nel DOM i nodi sono degli "oggetti". Dice: ma che è un "oggetto"? Semplice: la mia mano è un "oggetto", e ha il metodo "sganciaUnCeffone", che invocherò se non mi saprete rispondere all'interrogazione. E' più chiaro adesso?

Un "oggetto" può anche avere delle proprietà. Ad esempio, la mia mano ha la proprietà "dimensioni", il cui valore è lievemente superiore al quello della mano di Roma (ossia l'"oggetto" alunno di cognome "Roma").

 Dopo aver creato un nodo occorre assegnargli un papà (se preferite: genitore 1). Se, ad esempio, vogliamo che il noto "table" abbia come papà (sia figlio di) il nodo "p" con l'"id" di valore "demo", possiamo scrivere:

var tbl= document.createElement("table");
var demo = document.getElementById("demo");
demo.appendChild(tbl);

Naturalmente, siccome la "table" che abbiamo creato non ha (ancora) righe e colonne, non vedremo una beneamata fava. Per vedere qualcosa dovremo aggiungere almeno una riga con almeno una colonna. Cosicché il codice diventa:

var tbl= document.createElement("table");
var row= document.createElement("tr");
tbl.appendChild(row);
var col= document.createElement("td");
row.appendChild(col);

var demo = document.getElementById("demo");
demo.appendChild(tbl);

A questo punto vedremo... la solita beneamata fava! Già, perché abbiamo una tabella, con una riga e una colonna (una cella), ma dentro non c'è scritto niente. Cosa volete metterci nell'unica cella della tabella? Un testo? Va bene. Allora aggiungiamo al codice precedente:

var t = document.createTextNode("il prof è completamente pazzo");
col.appendChild(t);


 e il gioco è fatto. Volete di meglio? Ci volete mettere un'immagine? E allora scriviamo:

var myImg=document.createElement("img");
myImg.setAttribute("src", "http://www.w3schools.com/js/pic_htmltree.gif");
demo.appendChild(myImg);


Il codice completo (con il javascript, in grassetto, inserito direttamente nella pagina html) è il seguente:

<!DOCTYPE html>
<html>
<body>
<button id="myBtn" onclick="myFunction()">Cliccami</button>
<button id="clearBtn" onclick="document.getElementById('demo').innerHTML='';">Clear</button>
<script>
function myFunction() {
var demo = document.getElementById("demo");
if(demo.innerHTML!=""){return(null);}
var myImg=document.createElement("img");
myImg.setAttribute("src", "http://www.w3schools.com/js/pic_htmltree.gif");
demo.appendChild(myImg);
}
</script>
<p id="demo"></p>
</body>
</html>

Il risultato è questo:


Il minimo che vi chiedo, per ora, è di scegliere un'immagine migliore. Conoscete le mie preferenze, non deludetemi.

Conclusioni


Siete affogati? Non credo proprio. In classe vi spiegherò meglio, con il poco tempo che abbiamo e tutti i limiti della situation. Un giorno capirete perché la scuola pubblica è ridotta come sapete, e spero che farete qualcosa per rimediare. Quando le cose cambieranno io sarò sotto terra: pensate anche a me il giorno della vittoria.

giovedì 3 marzo 2016

Programmazione web lato client (3)

Oggi realizzeremo un semplice gioco, il tris. Al solito eccovi il link al source code e alla pagina web.
Per comodità, dal momento che l'interfaccia del gioco non occupa molto spazio sullo schermo, l'ho inserito anche in questa pagina, utilizzando un tag "iframe".


Nell'"head", oltre ai soliti riferimenti ai files esterni per il css e il codice javascript:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

troviamo una terza linea di codice:

<script>var j=1;</script>

il cui uso sarà spiegato nel seguito. Questo, infine, è il codice html che disegna la tabella e inserisce il pulsante per ricominciare il gioco.

<table align="center" border="1">
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr><td id="comandi" colspan="3">
<input type="button" onclick="restartAll();" value="Ricomincia">
</td></tr>
</table> 

Ci sono 9 celle, ognuna delle quali ha un attributo "class" (che specifica la classe css "riquadro") e un attributo onclick. Quando si passa il cursore su una delle celle, esso prende la forma di una manina. Cliccando sulla cella si richiama in esecuzione la funzione javascript "gulp" con la seguente sintassi:

j=gulp(this,j)

Ovvero si impone che il valore della variabile "j", inizializzata nell'intestazione (<script>var j=1;</script>) sia aggiornato dal valore di ritorno della funzione "gulp". A quest'ultima vengono passati "this" e il valore di "j" al momento del click. Come già sapete, la parola chiave "this" indica l'elemento su cui si è fatto click, in questo caso una delle 9 celle della tabella. Esaminiamo ora il codice della funzione gulp.

function gulp(t,j)
{if (t.innerHTML=="")
{
if(j==1){
t.innerHTML="<img src='homer.jpg'>";
}
else
{
t.innerHTML="<img src='roger.gif'>";
}
j=-j;
}
return(j)
}

La logica implementata dal codice è la seguente: se la cella è vuota, allora se j vale 1 si inserisce l'immagine "homer.jpg", altrimenti si inserisce l'immagine "roger.gif". Al termine si cambia segno a "j" e lo si restituisce come valore di ritorno della funzione. Così facendo, ogni volta che si clicca su una cella vuota vi si inserisce  una delle due immagini, a seconda che "j" sia 1 o -1, e lo si cambia di segno. Ovviamente, se la cella su cui si è cliccato non è vuota (perché contiene già una delle due immagini) non succede nulla.

Il pulsante "Ricomincia" reinizializza il gioco eseguendo il codice della funzione "restartAll":

function restartAll()
{
var tdList=document.getElementsByTagName("td");
for (i = 0; i < tdList.length; i++) { 
if (tdList[i].id=="")
     {tdList[i].innerHTML="";}
}
}

Si ottiene un riferimento alla lista delle 9+1 celle presenti sulla pagina (le 9 su cui si clicca più quella che ospita il pulsante) e gli si assegna il nome "tdList". Il resto del codice sarà di facile interpretazione dopo che avremo parlato in classe di liste (o variabili con indice) e di cicli for. Per il momento vi basti una descrizione generica di quello che fa il frammento di codice: eliminare il contenuto di tutte le celle della table ad eccezione di quella che ospita il pulsante, riconosciuta grazie all'attributo "id" il cui valore è "comandi" (si veda il codice html).

domenica 21 febbraio 2016

Programmazione web lato client (2)

Salve ragasciuoli, eccomi qua a spiegarvi il secondo esercizio...

Anche in questo caso abbiamo tre files: un html, un css e un js. Il riferimento al css e al js è nell'intestazione del file html:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

Abbiamo una table con un certo numero di immagini di automobili prese da Internet. Al centro della table c'è un'immagine più grande delle altre. Cliccando su una qualsiasi delle immagini più piccole che la circondano, questa prende il posto dell'immagine grande, e quest'ultima si posiziona al posto di quella piccola. L'effetto è scenografico, ma il codice necessario è veramente poco: quattro istruzioni.

Per prima cosa occorre assegnare un id all'immagine centrale. La scelta è stata quella di assegnargli il valore id="trg". Ciò fatto, abbiamo assegnato (ad ognuna delle immagini piccole) un gestore all'evento onclick, con la seguente sintassi:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Non mi soffermo sulla classe css "manina" perché so che non ne avete bisogno. Andiamo al sodo, cioè alla sintassi onclick="swapImg(this)". Già sapete che questo significa che, cliccando sull'immagine, viene chiamata in esecuzione la funzione swapImg alla quale viene passato il parametro "this". Sapete anche che "this" in italiano significa "questo" (e nella nobile lingua ciociara "chisse").

Ma "chisse" che? In questo caso "this" significa l'intero tag:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Ora guardiamo il codice della funzione swapImg, alla quale viene passato il parametro "chisse"... oops scusate, volevo dire "this".

function swapImg(p)
{
var x=p.src;
var trg=document.getElementById("trg")
p.src=trg.src;
trg.src=x;
}

La function accetta il parametro "p" (ma avremmo potuto chiamarlo come ci pare, salvo il divieto di usare "parole riservate"). Ovvio che se chiamiamo "p" il parametro, da ciò segue che, nel corso dell'esecuzione della function esso avrà il valore che gli è stato passato, vale a dire l'intero tag:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Quindi, nell'ambito dell'esecuzione della function swapImg, accade che "this" venga chiamato "p".

Perché non ho chiamato, anche nella function, il parametro con la parola "this"? Perché l'ho rinominato "p"? Semplice: perché "this" è una parola riservata, e dunque deve e può essere usata solo ed esclusivamente secondo le regole del linguaggio, e non come serve a noi. Claro? Casomai ve lo rispiego in laboratorio.

Ora, se "p" è tutto il tag, e questo ha degli attributi, che nel caso in esame sono:
  • class
  • onclick
  • src
noi possiamo leggerne il valore con l'istruzione: p.<nome_attributo>

Per cui, se vogliamo sapere qual è il valore dell'attributo "src" e assegnarlo alla variabile "x" possiamo scrivere:

var x=p.src;

Dunque, eseguita questa istruzione, nella variabile "x" è memorizzato il valore di "src" dell'immagine su cui abbiamo cliccato. L'istruzione successiva:

var trg=document.getElementById("trg")

assegna alla variabile "trg" il contenuto del tag "img" relativo all'immagine centrale (quella grande). In questo caso, siccome "trg" non è una parola riservata, per pura comodità (cioè fare una scelta che ci aiuta a ricordare che dde sse tratta) abbiamo usato come nome di variabile lo stesso nome dell'id nella pagina html. 

Vi siete persi? No problem, su questi dettagli torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo....

A questo punto, con l'istruzione:

p.src=trg.src;

assegniamo all'attributo "src" dell'immagine su cui abbiamo cliccato (che è il tag il cui id è "this") il valore dell'attributo "src" dell'immagine centrale (quella grande). Se ci fermassimo qui, il risultato sarebbe:
  • immagine su cui abbiamo cliccato: compare l'immagine centrale
  • immagine centrale: resta quello che c'era
Non ci resta, quindi, che mettere nell'immagine centrale quella su cui abbiamo cliccato. Lo facciamo con l'ultima istruzione:

trg.src=x;

Cioè assegniamo all'immagine centrale (il cui riferimento è "trg", come risultato dell'istruzione var trg=document.getElementById("trg")) un nuovo valore per l'attributo "src", che avevamo precedentemente prelevato e salvato nella variabile "x".

Due parole sullo swap


Ho assegnato alla function il nome "swapImage" in onore al fatto che nel gergo informatico il termine "swap" indica lo scambio di valori tra due variabili. Son Diego e vi spiego:

se x="pippo" e y="pluto", fare lo swap tra x e y significa che, dopo l'istruzione, si ha x="pluto" e y=pippo".

Vi ho anche spiegato, con un esempio "alcolico", in cosa consista lo swap. Lo ripeto. Immaginate di fare i camerieri in un locale e di dover portare a un tavolo un bicchiere di vino e uno di birra, ma che per errore avete messo il vino nel bicchiere della birra e la birra in quello del vino. Il caposala vi becca e vi ingiunge di rimediare. Che fare? Ovviamente avete bisogno di un terzo bicchiere: prima mettete il vino in questo bicchiere, poi versate la birra nel bicchiere giusto, poi travasate il vino dal terzo bicchiere in quello giusto per il vino.

Chiaro? Ricordatevi sempre, cari ragasciuoli, che molto spesso ciò che appare difficile è, in realtà, molto banale. Si tratta solo di imparare i rudimenti di un nuovo linguaggio.

Alla proxy (chiara allusione al fatto che prima o poi dovrete sapere cos'è un proxy).

sabato 13 febbraio 2016

Programmazione web lato client

Ho preparato un piccolo esempio per introdurre i miei studenti ai fondamentali della programmazione web lato client. L'esempio consta di tre files: il file htmlDoc.html, il file cssDoc.css e il file jsDoc.js, tutti nella stessa cartella.
Il sorgente di htmlDoc.html è il seguente:

<!DOCTYPE html>
<html>
<head>
<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>
</head>
<body>
<p>Lorem ipsum dolor sit amet, nec molestie lacus elit nunc lacinia. Fermentum consequat nec, nunc orci, et amet vitae accumsan et, sit amet quam porttitor. Metus interdum vitae nulla id mi, a vehicula, cum et. Vero justo dictum, vivamus euismod neque mi pede pulvinar blandit, ad et nec quis vel molestie, mattis ultricies lorem dapibus volutpat non. Eget sem nec scelerisque vehicula hac.</p>
<p>
Ornare et vel dictum dictum et, quis mauris tempus accumsan. Sed ligula, est integer justo viverra. Lacus porttitor blandit ac, sit in rerum sodales urna. Urna amet malesuada feugiat sed eu sodales, integer quae aenean pellentesque eget vulputate est, pretium cupiditate, praesent taciti sapien. Tristique sodales leo urna, aliquet consectetuer fermentum sit. In neque gravida ac nunc, interdum orci bibendum convallis lobortis ac nec, vitae nibh nulla sodales mi justo nulla, sed sit vestibulum. Vestibulum eget morbi dolor. Et quis massa ultricies et eros est, vel id. Fringilla curabitur non orci duis erat commodo. Amet mauris nulla dui imperdiet, pede elit semper dui.</p>
<p>
Nunc suspendisse vehicula ipsum. A turpis mollis nulla nunc nunc. Libero facilisis fermentum vel at, viverra duis dolor orci pede lacinia tempore, mauris a justo proin in tincidunt, euismod nibh egestas. Tempus eleifend sit, vel placerat lacus est, sed suspendisse ut, aliquam arcu neque a. Duis eu nec suscipit eros accumsan. Consectetuer maecenas sed ac velit etiam, ante eget mattis sapien vitae vivamus, est faucibus vestibulum wisi, commodo purus congue nunc velit nec nec, ante ligula quis orci sed consequatur potenti. Vivamus libero, dis consequat donec mattis diam vestibulum, dis nunc pellentesque, metus augue mollis nisl, sed adipiscing faucibus curabitur non pede ut. Sit at a suscipit sed quis, tincidunt metus tellus, id risus massa vehicula, quis in ut dis sollicitudin turpis sem, vitae egestas tortor. Ut lacinia pulvinar pulvinar in, quis elit elit eu sed, nulla lorem placerat tempor pellentesque in, ullamcorper urna. Ut dictum vel fusce eros lectus, justo nulla cum ligula eros quis vel, arcu ullamcorper, torquent pulvinar fringilla turpis fringilla dolor. Fermentum leo augue natoque, fringilla vestibulum quis. Quis eleifend eget est vestibulum.</p>
<p>
Vel mauris mattis sit id, eget diam urna dui vestibulum sed, eu vulputate in mi et sit laoreet. Turpis ullamcorper quis sapien semper et tortor, auctor non elit fringilla, montes pellentesque viverra condimentum volutpat risus, diam tincidunt, lorem quam. Porta pede duis sed massa. Neque sit vehicula porta nec cras tortor, sed lobortis donec mi odio faucibus, mollis neque proin pretium ut, nonummy nostra tellus placerat adipiscing vel. Ultrices leo, lorem sem cursus mauris.</p>

<select id="paragrafo">

  <option value="">Scegli un paragrafo</option>
  <option value="0">Paragrafo 1</option>
  <option value="1">Paragrafo 2</option>
  <option value="2">Paragrafo 3</option>
  <option value="3">Paragrafo 4</option>
</select>

<select id="styling">

  <option value="">Scegli uno stile</option>
  <option value="pace">Pace</option>
  <option value="viulenza">Viulenza</option>
  <option value="sconvolten">Sconvolten</option>
  <option value="delicatessen">Delicatessen</option>
</select>

<button type="button" onclick="changePar()">Applica</button> 

<button type="button" onclick="resetPar()">Resetta</button>

</body>

</html>

Si noti l'uso di testo Lorem ipsum.

Nell'intestazione sono referenziati i due files cssDoc.css e jsDoc.js:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

Il codice di cssDoc.css è il seguente:

body
{
margin-left: 15px;
margin-right:15px;
padding:0;
height:100%;
font-family: Verdana;
font-size: 20px;


p

{
margin-left:35px;
margin-right:35px;
}

.pace{color: blue;background-color: yellow }

.viulenza{color: red;background-color: black }
.sconvolten{color: white;background-color: black }
.delicatessen{color: blue;background-color: red }

In particolare si notino le tre dichiarazioni di classe css: .pace, .viulenza, .sconvolten e .delicatessen.

Tali stili non sono usati al primo caricamento della pagina. Lo saranno quando, dopo aver scelto un singolo paragrafo e lo stile da applicare, premeremo sul pulsante "Applica". La pressione del pulsante "Reset" riporterà la pagina nella condizione iniziale.

Il file javascript che "fa il lavoro" è il seguente:

function changePar()
{
var par=document.getElementById("paragrafo").value;
var stile=document.getElementById("styling").value;
var pList = document.getElementsByTagName("p");

pList[par].className=stile;

}

function resetPar(){

var pList = document.getElementsByTagName("p");

for (i = 0; i < pList.length; i++) {

pList[i].className="";
}

paragrafo.selectedIndex=0;

styling.selectedIndex=0;

}


Esso consta di due funzioni, changePar() e resetPar(), che vengono eseguite quando si premono, rispettivamente, i pulsanti "Applica" e "Reset".

Gi studenti sono invitati a copiare i sorgenti e ad eseguire il codice. Ciò fatto, possono provare a introdurre qualche modifica, ad esempio al file css. I più bravi potranno intervenire sul codice javascript per ulteriori modifiche al comportamento della pagina.

Non appena possibile realizzerò un filmato nel quale approfondirò gli aspetti più concettuali dell'esempio e, più in generale, della programmazione web lato client. Have fun guys.