KEMBAR78
Introduzione a JavaScript e jQuery (1/2) | PPT
Esercitazioni di Sistemi Distribuiti
2014/2015
Javascript e jQuery 1
Giuseppe Vizzari
Outline
• Concetti base
– Markup vs programmazione, scripting, client-side, AJAX...
• Un 'crash course' di JavaScript
– Variabili
– Array
– Strutture di controllo del flusso
– Funzioni
• Introduzione a jQuery ‘by example’
– Selezione e modifica di elementi di una pagina
– Gestione di eventi
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 2
Outline
• Concetti base
– Markup vs programmazione, scripting, client-side, AJAX...
• Un 'crash course' di JavaScript
– Variabili
– Array
– Strutture di controllo del flusso
– Funzioni
• Introduzione a jQuery ‘by example’
– Selezione e modifica di elementi di una pagina
– Gestione di eventi
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 3
Markup vs Programmazione
• Linguaggio di programmazione: utilizzato per comunicare istruzioni
a una macchina di calcolo, per definire programmi che controllino il
comportamento di un calcolatore
• Linguaggio di markup: utilizzato per annotare un documento in
modo tale che l'annotazione sia sintatticamente distinguibile dal
testo
• Esempi di linguaggi di markup:
– TeX (e LaTeX)
– SGML
– HTML, XHTML, XML
• Le annotazioni possono avere diverse finalità:
– di presentazione (definiscono come visualizzare il testo al quale sono
associate)
– procedurali (definiscono istruzioni per programmi che elaborino il testo
al quale sono associate)
– descrittive (etichettano semplicemente parti del testo, disaccoppiando
la struttura dalla presentazione del testo stesso)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 4
Linguaggi di Scripting
• Linguaggio di programmazione per l'automazione di compiti
altrimenti eseguibili da un utente umano all'interno di un
ambiente software
• Variano da linguaggi molto specifici per applicazioni e domini
ristretti (e.g. MAXScript per 3ds Max), a linguaggi general
purpose (e.g. Python)
• Caratteristiche tipiche:
– Semplicità ma...
– Specificità, orientamento a funzionalità limitate
– Interpretati, raramente compilati, spesso molto dinamici
• Curiosità
– Lisp (nella sua variante AutoLISP) è incluso nelle versioni complete
di AutoCAD
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 5
JavaScript
• JavaScript è un linguaggio di programmazione interpretato
inizialmente progettato per permettere l'esecuzione di script
all'interno di browser web, lato client, per l'interazione con
l'utente, la validazione di dati all'interno di form, la modifica di
documenti web senza effetto 'pagina bianca', ...
• JavaScript è dinamico, debolmente tipizzato, la cui sintassi è
stata influenzata dal C e da Java
• Non analizzeremo il linguaggio ad un livello di dettaglio analogo
rispetto a quello che avete visto per Java nei vari corsi di
programmazione...
• ... vedremo, tramite esempi concreti, come può essere utilizzato
per costruire pagine web dinamiche, capaci di riutilizzare servizi
web resi disponibili da terze parti, componendo – più che
programmando – applicazioni web
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 6
Lato client
• JavaScript è (di norma)
eseguito ‘lato client’
• Nel mondo web una serie di
tecnologie (non ultime le
servlet e JSP, ma anche PHP,
Ruby on Rails) rappresentano
tecnologie ‘lato server’
– Nella tipica architettura a 3 tier
le tecnologie lato server
realizzano gran parte delle
logiche applicative e accesso
ai dati (logic e data tier)
• Altre tecnologie ‘lato client’
sono ad esempio Flash, le
Applet di Java
A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 7
http://en.wikipedia.org/wiki/Multitier_architecture
Outline
• Concetti base
– Markup vs programmazione, scripting, client-side, AJAX...
• Un 'crash course' di JavaScript
– Variabili
– Array
– Strutture di controllo del flusso
– Funzioni
• Introduzione a JQuery ‘by example’
– Selezione e modifica di elementi di una pagina
– Gestione di eventi
A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 8
Testo consigliato
• Gli esercizi che verranno proposti sono
tratti dal testo JavaScript & jQuery: The
Missing Manual di David Sawyer
McFarland, ed. O'Reilly
• Gli esercizi e tutti file necessari per il loro
svolgimento sono scaricabili da
http://sawmac.com/js2e/
• Il libro tratta più temi rispetto a quelli che
verranno discussi a lezione e lo fa in
modo più approfondito
• Ulteriori risorse utili per approfondimento
e documentazione sono disponibili
gratuitamente in rete, ad esempio:
– JavaScript in generale:
http://www.quirksmode.org/js/contents.html
http://eloquentjavascript.net
– jQuery:
http://docs.jquery.com/Tutorials
http://www.w3schools.com/jquery/default.asp
A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 9
L'inevitabile 'Hello world!' (1)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link href="../_css/site.css" rel="stylesheet">
<script>
alert('hello world');
</script>
</head>
<body>
<div class="wrapper">
<div class="header”> [...] </div>
<div class="content”> [...] </div>
<div class="aside"> </div>
</div>
<div class="footer”> [...] </div>
</div>
</body>
</html>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 10
L'inevitabile 'Hello world!' (2)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link href="../_css/site.css" rel="stylesheet">
</head>
<body>
<div class="wrapper">
<div class="header”> [...] </div>
<div class="content">
<div class="main">
<h1>Writing to the Document Window</h1>
<script>
document.write('<p>Hello world!</p>');
</script>
</div>
<div class="aside"> </div>
</div>
<div class="footer”> [...] </div>
</div>
</body>
</html>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 11
Debugging – la console degli errori
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link href="../_css/site.css" rel="stylesheet">
<script src="../_js/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function() {
$('body').hide().fadeIn('slow);
});
</script>
</head>
<body>
<div class="wrapper">
<div class="header”> [...] </div>
<div class="content”> [...] </div>
<div class="aside"> </div>
</div>
<div class="footer”> [...] </div>
</div>
</body>
</html>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 12
Debugging – la console degli errori
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 13
Variabili (1)
<div class="content">
<div class="main">
<h1>Using a Variable</h1>
<script>
var firstName = 'Cookie';
var lastName = 'Monster';
//var lastName = 'Jar';
document.write('<p>');
document.write(firstName + ' ' + lastName);
document.write('</p>');
</script> </div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 14
Variabili (2)
<!DOCTYPE html>
<html>
<head>
[...]
<script>
var name = prompt('What is your name?', '');
</script>
</head>
<body>
<div class="wrapper">
<div class="header”> [...]
</div>
<div class="content">
<div class="main">
<h1>Using a Variable, Part II</h1>
<script>
document.write('<p>Welcome ' + name + '</p>');
</script>
</div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 15
Variabili e operatori –
approfondimento (1)
• Variabili non tipizzate, “tipo” dinamico
var lastName = 'Monster';
lastName = 3; // No problem, here...
• Attenzione alla semantica degli operatori, dipendente dal contenuto delle
variabili...
var numshoes = '2';
var numsocks = 4;
document.write('<p>' + numshoes + numsocks + '</p>')
document.write('<p>');
document.write(+ numshoes + numsocks);
document.write('</p>');
• Operatori matematici di Java consueti
var numsocks = 4;
var numshoes = 2;
numsocks = (numsocks/2) + numshoes;
numsocks += --numshoes;
numshoes /= 2;
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 16
Variabili e operatori –
approfondimento (2)
• Attenzione agli operatori di comparazione i noti == e !=,
ma anche === e !==
• I primi due, qualora le espressioni confrontate non siano dello
stesso tipo, cercano di effettuare una conversione, quindi
possono generare effetti sorprendenti ed errori
• Esempi:
– 0 == '0' ma 0 !== '0’
• In generale alcuni programmatori esperti (ad es. Douglas
Crockford, JavaScript architect di Yahoo) suggeriscono di usare
la versione che non effettua la conversione di tipo
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 17
Array (1)
<div class="content">
<div class="main">
<h1>Creating and Using Arrays</h1>
<script>
var authors = [ 'Ernest Hemingway',
'Charlotte Bronte',
'Dante Alighieri',
'Emily Dickinson'
];
document.write('<p>The first author is <strong>');
document.write(authors[0] + '</strong></p>');
document.write('<p>The last author is <strong>');
document.write(authors[authors.length-1] + '</strong></p>');
authors.unshift('Stan Lee');
document.write('<p>I almost forgot <strong>');
document.write(authors[0]);
document.write('</strong></p>');
authors.push('Umberto Eco');
document.write('<p>And finally... <strong>');
document.write(authors[authors.length-1]);
document.write('</strong></p>');
</script> </div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 18
Array (2)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 19
Array - approfondimento
• Sintassi analoga a Java ma nessuna necessità di
inizializzazione
• Attributo length, elementi dalla posizione 0 a length-1
• Natura essenzialmente dinamica
authors.push('Umberto Eco');
equivale a
authors[length]='Umberto Eco’;
• Funzioni varie di utilità, passaggio da array di stringhe a
stringhe e viceversa...
var myarr = ["Mack", "the", "Knife"];
document.write("<p>myarr: " + myarr + " </p>");
var flattened = myarr.join(" ");
document.write("<p>flattened: " + flattened + " </p>");
var newarr = flattened.split(" ");
document.write("<p>myarr: " + newarr + " </p>");
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 20
Strutture dati generalizzate
<div class="content">
<div class="main">
<h1>Using Conditional Statements</h1>
<script>
var myauthor = {name: 'Ernest Hemingway', "born": 1899, died: 1961 };
document.write('<p>The author's name is <strong>');
document.write(myauthor.name + '</strong></p>');
document.write('<p>He was born in <strong>');
document.write(myauthor["born"] + '</strong></p>');
document.write('<p>He died in <strong>');
document.write(myauthor.died + '</strong></p>');
delete myauthor.died;
myauthor.death=1961;
document.write('<p>This is another field <strong>' + myauthor.death);
document.write('</strong></p>');
if(myauthor.died === undefined)
document.write('<p>The previous one is now undefined.</p>');
</script> </div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 21
Strutture dati generalizzate -
approfondimento
• Oggetti JavaScript usabili per rappresentare record e strutture
composite
• Delimitatori parentesi graffe, struttura interna basata su property
var mailArchive = {0: "Dear nephew, ... (mail number 1)",
1: "(mail number 2)",
2: "(mail number 3)"};
for (var current = 0; current in mailArchive; current++) {
print("Processing e-mail #” + current);
print(": ” + mailArchive[current]);
}
• Strutture dinamiche, non “tipizzate”
var cat = {colour: "grey", name: "Spot", size: 46};
cat.size = 47;
delete cat.size; // Now (cat.size == undefined)
cat.weight = 5.5;
• Attenzione null e undefined sono oggetti veri e propri, il primo
rappresenta una variabile definita ma con valore ‘vuoto’, la seconda
un variabile non definita; inoltre:
– null == undefined ma null !== undefined
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 22
Controllo di flusso (1)
<div class="content">
<div class="main">
<h1>Using Conditional Statements</h1>
<script>
do {
var luckyNumber = prompt('What is your lucky number?','');
luckyNumber = parseInt(luckyNumber, 10);
} while (isNaN(luckyNumber));
if (luckyNumber == 7 ) {
document.write("<p>Hey, 7 is my lucky number too!</p>");
} else if (luckyNumber == 13 || luckyNumber == 24) {
document.write("<p>Wooh. " + luckyNumber);
document.write("? That's an unlucky number!</p>");
} else {
document.write("<p>The number " + luckyNumber);
document.write(“is lucky for you!</p>");
}
</script> </div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 23
Controllo di flusso - approfondimento
• Strutture di selezione - if
if (cond1){
// door #1
} else if (cond2){
// door #2
} else {
// door #3
}
• Strutture di selezione – switch
switch(var){
case 'val1':
// door #1
break;
case 'val2':
// door #2
break;
default:
// door #3
}
• Strutture di iterazione – while
while(cond){
// code to iterate
}
• Strutture di iterazione – do while
do {
// code to iterate
} while(cond);
• Strutture di iterazione – for
for(init; cond; step){
// code to iterate
}
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 24
Controllo di flusso e funzioni
<div class="content"> <div class="main"> <h1>A Simple Quiz</h1>
<script>
var score=0;
var questions = [
['How many moons does Earth have?', 1],
['How many moons does Saturn have?',31],
['How many moons does Venus have?', 0]
];
function askQuestion(question) {
var answer = prompt(question[0],'');
if (answer == question[1]) {
alert('Correct!');
score++;
} else {
alert('Sorry. The correct answer is ' + question[1]);
}
}
for (var i=0; i<questions.length; i++) {
askQuestion(questions[i]);
}
var message = 'You got ' + score;
message += ' out of ' + questions.length;
message += ' questions correct.';
document.write('<p>' + message + '</p>');
</script> </div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 25
Funzioni e scoping
<div class="content">
<div class="main">
<h1>Scoping...</h1>
<script>
var message = 'Global variable...';
function warningA() {
var message = 'Local variable...';
alert(message);
}
function warningB() {
alert(message);
}
warningA();
warningB();
alert(message);
</script>
</div>
</div>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 26
Outline
• Concetti base
– Markup vs programmazione, scripting, client-side, AJAX...
• Un 'crash course' di JavaScript
– Variabili
– Array
– Strutture di controllo del flusso
– Funzioni
• Introduzione a jQuery ‘by example’
– Selezione e modifica di elementi di una pagina
– Gestione di eventi
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 27
jQuery in breve...
• jQuery è un framework JavaScript che rende molto semplice la
scrittura di applicazioni web offrendo funzionalità quali
– manipolazione di HTML/DOM e CSS
– metodi per eventi HTML
– effetti e animazioni
– supporto a programmazione AJAX
– varie altre utilità (anche tramite plugin)
• Abbiamo scelto jQuery per il corso perché è
– diffuso, testato e manutenuto (utilizzato in siti come Dell, Digg, NBC
e da Google in alcuni progetti; è incluso in WordPress; ...)
– open source
– compatto (meno di 100kb, se compresso)
– può essere esteso con una serie di plugin di vario genere
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 28
Selezione e modifica elementi di una
pagina (1)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 29
Selezione e modifica elementi di una
pagina (2)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Using Functions</title>
<link href="../_css/site.css" rel="stylesheet">
</head>
<body>
<div class="header”> [...] </div>
<div class="content">
<div class="main">
<h1>Auto-Pull Quotes</h1>
<h2>Vestibulum semper</h2>
<p>Vestibulum semper [...] <span class="pq">Vivamus justo mi, aliquam vitae, eleifend et, lobortis quis,
eros.</span>
[...] </p>
<h2>Morbi dictum</h2>
<p>Donec at sapien [...] <span class="pq">Etiam mattis. Donec sed diam nec odio molestie iaculis.</span>
[...] </p>
<h2>Praesent sed est</h2>
<p>Praesent sed est ac metus facilisis [...] </p>
<p>Integer lacus. [...] </p>
</div>
</div>
<div class="footer”> [...] </div>
</body>
</html>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 30
Selezione e modifica elementi di una
pagina (3)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 31
Selezione e modifica elementi di una
pagina (4)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 32
Selezione e modifica elementi di una
pagina (5)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Using Functions</title>
<link href="../_css/site.css" rel="stylesheet">
<style>
.pullquote {
float: right;
clear: right;
width: 200px;
border: 1px solid black;
padding: 10px;
font-size: 20px;
background-color:rgb(195,151,51);
margin: 20px 0 10px 10px;
font-style: italic;
color: rgb(255,255,255);
}
</style>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 33
Selezione e modifica elementi di una
pagina (6)
<head>
[...]
<script src="../_js/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function() {
$('span.pq').each(function() {
var quote=$(this).clone();
quote.removeClass('pq');
quote.addClass('pullquote');
$(this).before(quote);
}); // end each
}); // end ready
</script>
</head>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 34
Elementi base di jQuery (1)
• La sintassi di jQuery è specificamente orientata a permettere una rapida e
semplice selezione di elementi del documento HTML
• La sintassi base di un comando jQuery è
$(selector).action()
– Il $ definisce l’accesso a funzionalità offerte da jQuery
– selector viene utilizzato per specificare una sorta di query per selezionare
una parte del documento HTML
– action specifica un’azione da effettuare sull’elemento stesso
• La porzione
$(document).ready(function() {
[...]
}); // end ready
indica che vogliamo effettuare l’azione ready sull’oggetto document
passando come parametro una funzione anonima, specificata per esteso
• L’azione ready specifica che il parametro ricevuto, una funzione, va
richiamata non appena il documento è ‘pronto’, ovvero è stato
completamente caricato
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 35
Elementi base di jQuery (2)
• Quello che vorremmo fare, nel nostro esempio, è selezionare le
porzioni di documento negli span di classe pq, clonarli dandogli
al contempo lo stile desiderato
• Il selettore per individuare tutti gli span di classe pq è $
('span.pq')
• Per iterare su un insieme di elementi jQuery offre la funzione
each
• La porzione
$('span.pq').each(function() {
[...]
}); // end each
permette di specificare una funzione anonima che va applicata
ad ogni span di classe pq
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 36
Elementi base di jQuery (3)
• A questo punto possiamo operare sui singoli span...
• In particolare il selettore $(this), trovandoci all’interno di una
funzione chiamata (implicitamente) su uno degli span stessi, ci
permette di ottenere il riferimento che ci serve
• La porzione
var quote=$(this).clone();
quote.removeClass('pq');
quote.addClass('pullquote');
$(this).before(quote);
permette quindi di
– clonare lo span nella variabile quote,
– rimuoverne la classe pq,
– aggiungerne la classe pullquote,
– aggiungere la variabile stessa al documento, appena prima dello
span stesso
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 37
Gestione di eventi e modifica dinamica
di una pagina (1)
<!DOCTYPE html>
<html>
<head> <meta charset="UTF-8">
<title>A One Page Faq</title>
<link href="../_css/site.css" rel="stylesheet">
</head>
<body>
<div class="header"> [...] </div>
<div class="content”>
<div class="main">
<h1>A One Page FAQ</h1>
<h2>I've heard that JavaScript is the long-lost fountain of youth. Is this true?</h2>
<div class="answer"> <p>Why, yes it is! Studies prove that learning JavaScript freshens the mind and extends
life span by several hundred years. (Note: some scientists disagree with these claims.)</p> </div>
<h2>Can JavaScript really solve all of my problems?</h2>
<div class="answer”> <p>Why, yes it can! It's the most versatile programming language ever created and is
trained to provide financial management advice, life-saving CPR, and even to take care of household pets.</p>
</div>
<h2>Is there nothing JavaScript <em>can&#8217;t</em> do?</h2>
<div class="answer"> <p>Why, no there isn&#8217;t! It&#8217;s even able to write its own public relations-
oriented Frequently Asked Questions pages. Now that&#8217;s one smart programming language!</p> </div>
</div>
</div>
<div class="footer"> [...] </div>
</div>
</body>
</html>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 38
Gestione di eventi e modifica dinamica
di una pagina (2)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 39
Gestione di eventi e modifica dinamica
di una pagina (3)
<!DOCTYPE html>
<html>
<head> <meta charset="UTF-8">
<title>A One Page Faq</title>
<link href="../_css/site.css" rel="stylesheet">
<style type="text/css">
h2 {
background: url(../_images/open.png) no-repeat 0 11px;
padding: 10px 0 0 25px;
cursor: pointer;
}
h2.close {
background-image: url(../_images/close.png);
}
.answer {
margin-left: 25px;
}
</style>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 40
Gestione di eventi e modifica dinamica
di una pagina (4)
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 41
Gestione di eventi e modifica dinamica
di una pagina (5)
<script src="../_js/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function() {
$('.answer').hide();
$('.main h2').toggle(
function() {
$(this).next('.answer').slideDown();
$(this).addClass('close');
},
function() {
$(this).next('.answer').fadeOut();
$(this).removeClass('close');
}
); // end toggle
}); // end ready
</script>
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 42
Ulteriori elementi di base di jQuery
• Tramite la tecnica precedentemente illustrata definiamo il da
farsi al caricamento della pagina
• La porzione di codice
$('.answer').hide();
$('.main h2').toggle(
[...]
}
specifica che:
– in primis, i div di classe answer devono essere nascosti
– in seconda battuta, ai tag h2 che siano figli di un div di classe
main, va applicata la funzione toggle
[segue...]
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 43
Ulteriori elementi di base di jQuery
• La funzione toggle permette di associare a un elemento due diverse
funzioni, da chiamare rispettivamente per ogni click dispari e pari
• In questa porzione di codice
$('.main h2').toggle(
function() {
$(this).next('.answer').slideDown();
$(this).addClass('close');
},
function() {
$(this).next('.answer').fadeOut();
$(this).removeClass('close');
}
); // end toggle
}
si associano due funzioni anonime:
– la prima: (i) seleziona il primo div di tipo answer che segue l’oggetto corrente
(il tag h2) e vi applica la funzione slideDown, (ii) aggiunge la classe close
all’oggetto corrente
– la seconda: (i) seleziona il primo div di tipo answer che segue l’oggetto
corrente e vi applica la funzione fadeOut, (ii) aggiunge la classe close
all’oggetto corrente
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 44
Prossima lezione
• Ancora jQuery
– Approfondimento sulla gestione di eventi
– Ulteriori esempi di interfacce dinamiche
– Validazione di form
– Ajax di base
• Un esempio articolato
A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 45

Introduzione a JavaScript e jQuery (1/2)

  • 1.
    Esercitazioni di SistemiDistribuiti 2014/2015 Javascript e jQuery 1 Giuseppe Vizzari
  • 2.
    Outline • Concetti base –Markup vs programmazione, scripting, client-side, AJAX... • Un 'crash course' di JavaScript – Variabili – Array – Strutture di controllo del flusso – Funzioni • Introduzione a jQuery ‘by example’ – Selezione e modifica di elementi di una pagina – Gestione di eventi A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 2
  • 3.
    Outline • Concetti base –Markup vs programmazione, scripting, client-side, AJAX... • Un 'crash course' di JavaScript – Variabili – Array – Strutture di controllo del flusso – Funzioni • Introduzione a jQuery ‘by example’ – Selezione e modifica di elementi di una pagina – Gestione di eventi A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 3
  • 4.
    Markup vs Programmazione •Linguaggio di programmazione: utilizzato per comunicare istruzioni a una macchina di calcolo, per definire programmi che controllino il comportamento di un calcolatore • Linguaggio di markup: utilizzato per annotare un documento in modo tale che l'annotazione sia sintatticamente distinguibile dal testo • Esempi di linguaggi di markup: – TeX (e LaTeX) – SGML – HTML, XHTML, XML • Le annotazioni possono avere diverse finalità: – di presentazione (definiscono come visualizzare il testo al quale sono associate) – procedurali (definiscono istruzioni per programmi che elaborino il testo al quale sono associate) – descrittive (etichettano semplicemente parti del testo, disaccoppiando la struttura dalla presentazione del testo stesso) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 4
  • 5.
    Linguaggi di Scripting •Linguaggio di programmazione per l'automazione di compiti altrimenti eseguibili da un utente umano all'interno di un ambiente software • Variano da linguaggi molto specifici per applicazioni e domini ristretti (e.g. MAXScript per 3ds Max), a linguaggi general purpose (e.g. Python) • Caratteristiche tipiche: – Semplicità ma... – Specificità, orientamento a funzionalità limitate – Interpretati, raramente compilati, spesso molto dinamici • Curiosità – Lisp (nella sua variante AutoLISP) è incluso nelle versioni complete di AutoCAD A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 5
  • 6.
    JavaScript • JavaScript èun linguaggio di programmazione interpretato inizialmente progettato per permettere l'esecuzione di script all'interno di browser web, lato client, per l'interazione con l'utente, la validazione di dati all'interno di form, la modifica di documenti web senza effetto 'pagina bianca', ... • JavaScript è dinamico, debolmente tipizzato, la cui sintassi è stata influenzata dal C e da Java • Non analizzeremo il linguaggio ad un livello di dettaglio analogo rispetto a quello che avete visto per Java nei vari corsi di programmazione... • ... vedremo, tramite esempi concreti, come può essere utilizzato per costruire pagine web dinamiche, capaci di riutilizzare servizi web resi disponibili da terze parti, componendo – più che programmando – applicazioni web A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 6
  • 7.
    Lato client • JavaScriptè (di norma) eseguito ‘lato client’ • Nel mondo web una serie di tecnologie (non ultime le servlet e JSP, ma anche PHP, Ruby on Rails) rappresentano tecnologie ‘lato server’ – Nella tipica architettura a 3 tier le tecnologie lato server realizzano gran parte delle logiche applicative e accesso ai dati (logic e data tier) • Altre tecnologie ‘lato client’ sono ad esempio Flash, le Applet di Java A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 7 http://en.wikipedia.org/wiki/Multitier_architecture
  • 8.
    Outline • Concetti base –Markup vs programmazione, scripting, client-side, AJAX... • Un 'crash course' di JavaScript – Variabili – Array – Strutture di controllo del flusso – Funzioni • Introduzione a JQuery ‘by example’ – Selezione e modifica di elementi di una pagina – Gestione di eventi A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 8
  • 9.
    Testo consigliato • Gliesercizi che verranno proposti sono tratti dal testo JavaScript & jQuery: The Missing Manual di David Sawyer McFarland, ed. O'Reilly • Gli esercizi e tutti file necessari per il loro svolgimento sono scaricabili da http://sawmac.com/js2e/ • Il libro tratta più temi rispetto a quelli che verranno discussi a lezione e lo fa in modo più approfondito • Ulteriori risorse utili per approfondimento e documentazione sono disponibili gratuitamente in rete, ad esempio: – JavaScript in generale: http://www.quirksmode.org/js/contents.html http://eloquentjavascript.net – jQuery: http://docs.jquery.com/Tutorials http://www.w3schools.com/jquery/default.asp A.A. 2013/2014 Esercitazioni di Sistemi Distribuiti 9
  • 10.
    L'inevitabile 'Hello world!'(1) <!doctype html> <html> <head> <meta charset="UTF-8"> <title>Hello World</title> <link href="../_css/site.css" rel="stylesheet"> <script> alert('hello world'); </script> </head> <body> <div class="wrapper"> <div class="header”> [...] </div> <div class="content”> [...] </div> <div class="aside"> </div> </div> <div class="footer”> [...] </div> </div> </body> </html> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 10
  • 11.
    L'inevitabile 'Hello world!'(2) <!doctype html> <html> <head> <meta charset="UTF-8"> <title>Hello World</title> <link href="../_css/site.css" rel="stylesheet"> </head> <body> <div class="wrapper"> <div class="header”> [...] </div> <div class="content"> <div class="main"> <h1>Writing to the Document Window</h1> <script> document.write('<p>Hello world!</p>'); </script> </div> <div class="aside"> </div> </div> <div class="footer”> [...] </div> </div> </body> </html> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 11
  • 12.
    Debugging – laconsole degli errori <!doctype html> <html> <head> <meta charset="UTF-8"> <title>Hello World</title> <link href="../_css/site.css" rel="stylesheet"> <script src="../_js/jquery-1.7.2.min.js"></script> <script> $(document).ready(function() { $('body').hide().fadeIn('slow); }); </script> </head> <body> <div class="wrapper"> <div class="header”> [...] </div> <div class="content”> [...] </div> <div class="aside"> </div> </div> <div class="footer”> [...] </div> </div> </body> </html> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 12
  • 13.
    Debugging – laconsole degli errori A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 13
  • 14.
    Variabili (1) <div class="content"> <divclass="main"> <h1>Using a Variable</h1> <script> var firstName = 'Cookie'; var lastName = 'Monster'; //var lastName = 'Jar'; document.write('<p>'); document.write(firstName + ' ' + lastName); document.write('</p>'); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 14
  • 15.
    Variabili (2) <!DOCTYPE html> <html> <head> [...] <script> varname = prompt('What is your name?', ''); </script> </head> <body> <div class="wrapper"> <div class="header”> [...] </div> <div class="content"> <div class="main"> <h1>Using a Variable, Part II</h1> <script> document.write('<p>Welcome ' + name + '</p>'); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 15
  • 16.
    Variabili e operatori– approfondimento (1) • Variabili non tipizzate, “tipo” dinamico var lastName = 'Monster'; lastName = 3; // No problem, here... • Attenzione alla semantica degli operatori, dipendente dal contenuto delle variabili... var numshoes = '2'; var numsocks = 4; document.write('<p>' + numshoes + numsocks + '</p>') document.write('<p>'); document.write(+ numshoes + numsocks); document.write('</p>'); • Operatori matematici di Java consueti var numsocks = 4; var numshoes = 2; numsocks = (numsocks/2) + numshoes; numsocks += --numshoes; numshoes /= 2; A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 16
  • 17.
    Variabili e operatori– approfondimento (2) • Attenzione agli operatori di comparazione i noti == e !=, ma anche === e !== • I primi due, qualora le espressioni confrontate non siano dello stesso tipo, cercano di effettuare una conversione, quindi possono generare effetti sorprendenti ed errori • Esempi: – 0 == '0' ma 0 !== '0’ • In generale alcuni programmatori esperti (ad es. Douglas Crockford, JavaScript architect di Yahoo) suggeriscono di usare la versione che non effettua la conversione di tipo A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 17
  • 18.
    Array (1) <div class="content"> <divclass="main"> <h1>Creating and Using Arrays</h1> <script> var authors = [ 'Ernest Hemingway', 'Charlotte Bronte', 'Dante Alighieri', 'Emily Dickinson' ]; document.write('<p>The first author is <strong>'); document.write(authors[0] + '</strong></p>'); document.write('<p>The last author is <strong>'); document.write(authors[authors.length-1] + '</strong></p>'); authors.unshift('Stan Lee'); document.write('<p>I almost forgot <strong>'); document.write(authors[0]); document.write('</strong></p>'); authors.push('Umberto Eco'); document.write('<p>And finally... <strong>'); document.write(authors[authors.length-1]); document.write('</strong></p>'); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 18
  • 19.
    Array (2) A.A. 2014/2015Esercitazioni di Sistemi Distribuiti 19
  • 20.
    Array - approfondimento •Sintassi analoga a Java ma nessuna necessità di inizializzazione • Attributo length, elementi dalla posizione 0 a length-1 • Natura essenzialmente dinamica authors.push('Umberto Eco'); equivale a authors[length]='Umberto Eco’; • Funzioni varie di utilità, passaggio da array di stringhe a stringhe e viceversa... var myarr = ["Mack", "the", "Knife"]; document.write("<p>myarr: " + myarr + " </p>"); var flattened = myarr.join(" "); document.write("<p>flattened: " + flattened + " </p>"); var newarr = flattened.split(" "); document.write("<p>myarr: " + newarr + " </p>"); A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 20
  • 21.
    Strutture dati generalizzate <divclass="content"> <div class="main"> <h1>Using Conditional Statements</h1> <script> var myauthor = {name: 'Ernest Hemingway', "born": 1899, died: 1961 }; document.write('<p>The author's name is <strong>'); document.write(myauthor.name + '</strong></p>'); document.write('<p>He was born in <strong>'); document.write(myauthor["born"] + '</strong></p>'); document.write('<p>He died in <strong>'); document.write(myauthor.died + '</strong></p>'); delete myauthor.died; myauthor.death=1961; document.write('<p>This is another field <strong>' + myauthor.death); document.write('</strong></p>'); if(myauthor.died === undefined) document.write('<p>The previous one is now undefined.</p>'); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 21
  • 22.
    Strutture dati generalizzate- approfondimento • Oggetti JavaScript usabili per rappresentare record e strutture composite • Delimitatori parentesi graffe, struttura interna basata su property var mailArchive = {0: "Dear nephew, ... (mail number 1)", 1: "(mail number 2)", 2: "(mail number 3)"}; for (var current = 0; current in mailArchive; current++) { print("Processing e-mail #” + current); print(": ” + mailArchive[current]); } • Strutture dinamiche, non “tipizzate” var cat = {colour: "grey", name: "Spot", size: 46}; cat.size = 47; delete cat.size; // Now (cat.size == undefined) cat.weight = 5.5; • Attenzione null e undefined sono oggetti veri e propri, il primo rappresenta una variabile definita ma con valore ‘vuoto’, la seconda un variabile non definita; inoltre: – null == undefined ma null !== undefined A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 22
  • 23.
    Controllo di flusso(1) <div class="content"> <div class="main"> <h1>Using Conditional Statements</h1> <script> do { var luckyNumber = prompt('What is your lucky number?',''); luckyNumber = parseInt(luckyNumber, 10); } while (isNaN(luckyNumber)); if (luckyNumber == 7 ) { document.write("<p>Hey, 7 is my lucky number too!</p>"); } else if (luckyNumber == 13 || luckyNumber == 24) { document.write("<p>Wooh. " + luckyNumber); document.write("? That's an unlucky number!</p>"); } else { document.write("<p>The number " + luckyNumber); document.write(“is lucky for you!</p>"); } </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 23
  • 24.
    Controllo di flusso- approfondimento • Strutture di selezione - if if (cond1){ // door #1 } else if (cond2){ // door #2 } else { // door #3 } • Strutture di selezione – switch switch(var){ case 'val1': // door #1 break; case 'val2': // door #2 break; default: // door #3 } • Strutture di iterazione – while while(cond){ // code to iterate } • Strutture di iterazione – do while do { // code to iterate } while(cond); • Strutture di iterazione – for for(init; cond; step){ // code to iterate } A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 24
  • 25.
    Controllo di flussoe funzioni <div class="content"> <div class="main"> <h1>A Simple Quiz</h1> <script> var score=0; var questions = [ ['How many moons does Earth have?', 1], ['How many moons does Saturn have?',31], ['How many moons does Venus have?', 0] ]; function askQuestion(question) { var answer = prompt(question[0],''); if (answer == question[1]) { alert('Correct!'); score++; } else { alert('Sorry. The correct answer is ' + question[1]); } } for (var i=0; i<questions.length; i++) { askQuestion(questions[i]); } var message = 'You got ' + score; message += ' out of ' + questions.length; message += ' questions correct.'; document.write('<p>' + message + '</p>'); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 25
  • 26.
    Funzioni e scoping <divclass="content"> <div class="main"> <h1>Scoping...</h1> <script> var message = 'Global variable...'; function warningA() { var message = 'Local variable...'; alert(message); } function warningB() { alert(message); } warningA(); warningB(); alert(message); </script> </div> </div> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 26
  • 27.
    Outline • Concetti base –Markup vs programmazione, scripting, client-side, AJAX... • Un 'crash course' di JavaScript – Variabili – Array – Strutture di controllo del flusso – Funzioni • Introduzione a jQuery ‘by example’ – Selezione e modifica di elementi di una pagina – Gestione di eventi A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 27
  • 28.
    jQuery in breve... •jQuery è un framework JavaScript che rende molto semplice la scrittura di applicazioni web offrendo funzionalità quali – manipolazione di HTML/DOM e CSS – metodi per eventi HTML – effetti e animazioni – supporto a programmazione AJAX – varie altre utilità (anche tramite plugin) • Abbiamo scelto jQuery per il corso perché è – diffuso, testato e manutenuto (utilizzato in siti come Dell, Digg, NBC e da Google in alcuni progetti; è incluso in WordPress; ...) – open source – compatto (meno di 100kb, se compresso) – può essere esteso con una serie di plugin di vario genere A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 28
  • 29.
    Selezione e modificaelementi di una pagina (1) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 29
  • 30.
    Selezione e modificaelementi di una pagina (2) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Using Functions</title> <link href="../_css/site.css" rel="stylesheet"> </head> <body> <div class="header”> [...] </div> <div class="content"> <div class="main"> <h1>Auto-Pull Quotes</h1> <h2>Vestibulum semper</h2> <p>Vestibulum semper [...] <span class="pq">Vivamus justo mi, aliquam vitae, eleifend et, lobortis quis, eros.</span> [...] </p> <h2>Morbi dictum</h2> <p>Donec at sapien [...] <span class="pq">Etiam mattis. Donec sed diam nec odio molestie iaculis.</span> [...] </p> <h2>Praesent sed est</h2> <p>Praesent sed est ac metus facilisis [...] </p> <p>Integer lacus. [...] </p> </div> </div> <div class="footer”> [...] </div> </body> </html> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 30
  • 31.
    Selezione e modificaelementi di una pagina (3) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 31
  • 32.
    Selezione e modificaelementi di una pagina (4) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 32
  • 33.
    Selezione e modificaelementi di una pagina (5) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Using Functions</title> <link href="../_css/site.css" rel="stylesheet"> <style> .pullquote { float: right; clear: right; width: 200px; border: 1px solid black; padding: 10px; font-size: 20px; background-color:rgb(195,151,51); margin: 20px 0 10px 10px; font-style: italic; color: rgb(255,255,255); } </style> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 33
  • 34.
    Selezione e modificaelementi di una pagina (6) <head> [...] <script src="../_js/jquery-1.7.2.min.js"></script> <script> $(document).ready(function() { $('span.pq').each(function() { var quote=$(this).clone(); quote.removeClass('pq'); quote.addClass('pullquote'); $(this).before(quote); }); // end each }); // end ready </script> </head> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 34
  • 35.
    Elementi base dijQuery (1) • La sintassi di jQuery è specificamente orientata a permettere una rapida e semplice selezione di elementi del documento HTML • La sintassi base di un comando jQuery è $(selector).action() – Il $ definisce l’accesso a funzionalità offerte da jQuery – selector viene utilizzato per specificare una sorta di query per selezionare una parte del documento HTML – action specifica un’azione da effettuare sull’elemento stesso • La porzione $(document).ready(function() { [...] }); // end ready indica che vogliamo effettuare l’azione ready sull’oggetto document passando come parametro una funzione anonima, specificata per esteso • L’azione ready specifica che il parametro ricevuto, una funzione, va richiamata non appena il documento è ‘pronto’, ovvero è stato completamente caricato A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 35
  • 36.
    Elementi base dijQuery (2) • Quello che vorremmo fare, nel nostro esempio, è selezionare le porzioni di documento negli span di classe pq, clonarli dandogli al contempo lo stile desiderato • Il selettore per individuare tutti gli span di classe pq è $ ('span.pq') • Per iterare su un insieme di elementi jQuery offre la funzione each • La porzione $('span.pq').each(function() { [...] }); // end each permette di specificare una funzione anonima che va applicata ad ogni span di classe pq A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 36
  • 37.
    Elementi base dijQuery (3) • A questo punto possiamo operare sui singoli span... • In particolare il selettore $(this), trovandoci all’interno di una funzione chiamata (implicitamente) su uno degli span stessi, ci permette di ottenere il riferimento che ci serve • La porzione var quote=$(this).clone(); quote.removeClass('pq'); quote.addClass('pullquote'); $(this).before(quote); permette quindi di – clonare lo span nella variabile quote, – rimuoverne la classe pq, – aggiungerne la classe pullquote, – aggiungere la variabile stessa al documento, appena prima dello span stesso A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 37
  • 38.
    Gestione di eventie modifica dinamica di una pagina (1) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>A One Page Faq</title> <link href="../_css/site.css" rel="stylesheet"> </head> <body> <div class="header"> [...] </div> <div class="content”> <div class="main"> <h1>A One Page FAQ</h1> <h2>I've heard that JavaScript is the long-lost fountain of youth. Is this true?</h2> <div class="answer"> <p>Why, yes it is! Studies prove that learning JavaScript freshens the mind and extends life span by several hundred years. (Note: some scientists disagree with these claims.)</p> </div> <h2>Can JavaScript really solve all of my problems?</h2> <div class="answer”> <p>Why, yes it can! It's the most versatile programming language ever created and is trained to provide financial management advice, life-saving CPR, and even to take care of household pets.</p> </div> <h2>Is there nothing JavaScript <em>can&#8217;t</em> do?</h2> <div class="answer"> <p>Why, no there isn&#8217;t! It&#8217;s even able to write its own public relations- oriented Frequently Asked Questions pages. Now that&#8217;s one smart programming language!</p> </div> </div> </div> <div class="footer"> [...] </div> </div> </body> </html> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 38
  • 39.
    Gestione di eventie modifica dinamica di una pagina (2) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 39
  • 40.
    Gestione di eventie modifica dinamica di una pagina (3) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>A One Page Faq</title> <link href="../_css/site.css" rel="stylesheet"> <style type="text/css"> h2 { background: url(../_images/open.png) no-repeat 0 11px; padding: 10px 0 0 25px; cursor: pointer; } h2.close { background-image: url(../_images/close.png); } .answer { margin-left: 25px; } </style> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 40
  • 41.
    Gestione di eventie modifica dinamica di una pagina (4) A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 41
  • 42.
    Gestione di eventie modifica dinamica di una pagina (5) <script src="../_js/jquery-1.7.2.min.js"></script> <script> $(document).ready(function() { $('.answer').hide(); $('.main h2').toggle( function() { $(this).next('.answer').slideDown(); $(this).addClass('close'); }, function() { $(this).next('.answer').fadeOut(); $(this).removeClass('close'); } ); // end toggle }); // end ready </script> A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 42
  • 43.
    Ulteriori elementi dibase di jQuery • Tramite la tecnica precedentemente illustrata definiamo il da farsi al caricamento della pagina • La porzione di codice $('.answer').hide(); $('.main h2').toggle( [...] } specifica che: – in primis, i div di classe answer devono essere nascosti – in seconda battuta, ai tag h2 che siano figli di un div di classe main, va applicata la funzione toggle [segue...] A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 43
  • 44.
    Ulteriori elementi dibase di jQuery • La funzione toggle permette di associare a un elemento due diverse funzioni, da chiamare rispettivamente per ogni click dispari e pari • In questa porzione di codice $('.main h2').toggle( function() { $(this).next('.answer').slideDown(); $(this).addClass('close'); }, function() { $(this).next('.answer').fadeOut(); $(this).removeClass('close'); } ); // end toggle } si associano due funzioni anonime: – la prima: (i) seleziona il primo div di tipo answer che segue l’oggetto corrente (il tag h2) e vi applica la funzione slideDown, (ii) aggiunge la classe close all’oggetto corrente – la seconda: (i) seleziona il primo div di tipo answer che segue l’oggetto corrente e vi applica la funzione fadeOut, (ii) aggiunge la classe close all’oggetto corrente A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 44
  • 45.
    Prossima lezione • AncorajQuery – Approfondimento sulla gestione di eventi – Ulteriori esempi di interfacce dinamiche – Validazione di form – Ajax di base • Un esempio articolato A.A. 2014/2015 Esercitazioni di Sistemi Distribuiti 45

Editor's Notes

  • #11 Esempio Chapter 1
  • #12 Esempio Chapter 1
  • #13 Esempio Chapter 1
  • #14 Esempio Chapter 1
  • #15 Esempio Chapter 2
  • #16 Esempio Chapter 2
  • #19 Esempio Chapter 2 complete array (pasticciato)
  • #20 Esempio Chapter 2 complete array (pasticciato)
  • #21 Esempio Chapter 2 complete array (pasticciato)
  • #22 Esempio Chapter 2 complete data struct
  • #24 Esempio Chapter 3 complete conditional
  • #26 Esempio Chapter 3 complete quiz (pasticciato)
  • #27 Esempio Chapter 3 complete scoping (pasticciato)
  • #30 chapter4 pull quotes
  • #39 chapter 5 faq