JavaScript
Transcript
JavaScript
Introduzione alle funzioni Le funzioni sono un comodo contenitore in cui racchiudere il codice. Anziché “sporcare la pagina” mischiando codice HTML e linguaggio JavaScript, è sufficiente inserire il codice in una funzione e richiamare la funzione quando occorre. La sintassi necessaria per creare una funzione è questa: function nomeFunzione() { // qui il nostro codice } Insomma tutto il codice da noi elaborato deve essere contenuto all’interno delle parentesi graffe, che delimitano l’inizio e la chiusura della funzione (Con Windows per digitare le parentesi graffe comporre la combinazione di tasti: AltGr+Shift+parentesi quadre. Lo “Shift” è il tasto con la freccia necessario per scrivere le maiuscole, da non confondere con il “Caps Lock”). La funzione che abbiamo appena creato si richiama poi con: nomeFunzione(); da inserire nell’elemento <script>, all’interno dell’head, nel corpo della pagina, oppure all’interno di un elemento, da richiamare tramite un evento. Con questo codice non facciamo che richiamare il gruppo di istruzioni contenuti all’interno della funzione. Per mantenere poi ordine all’interno della pagina, dobbiamo inserire tutte le nostre funzioni all’interno della HEAD del documento, e richiamarle nella stessa HEAD o nel BODY (come detto – facendovi riferimento tramite un evento oppure inserendole nel punto esatto in cui ci serve richiamarle). Vediamo un semplice esempio, per afferrare subito il concetto. Da inserire nel tag <script>: function saluta() { alert ("ciao"); } saluta(); C’è una particolarità da notare che finora non abbiamo ancora espresso con chiarezza, ma che dovrebbe essere emersa dai numerosi esempi presentati: ogni istruzione JavaScript deve essere conclusa con un punto e virgola. Se rielaboriamo alcuni degli esempi, esaminati nelle pagine precedenti, tramite l’utilizzo delle funzioni otteniamo una sintassi molto più “pulita”: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Corso JavaScript ad esempi</title> <script type="text/javascript"> /* prima funzione */ function saluta() { alert("ciao"); } /* seconda funzione */ function apriFinestra() { /* creo una variabile contenente la larghezza della finestra */ larghFinestra=500; /* creo una variabile contenente l'altezza della finestra */ altezFinestra=500; /* creo una variabile e mi ricavo il valore della * posizione della finestra a sinistra dello schermo */ sinistra=screen.width-larghFinestra+20; /* creo una variabile e mi ricavo il valore della * posizione della finestra dall'alto dello schermo */ alto=(screen.height-larghFinestra)/2; window.open("http://www.html.it","", "left="+sinistra+",top="+alto+", width="+larghFinestra+", height="+altezFinestra+", menubar, toolbar"); } /* terza funzione */ function scriviRisoluzione(){ document.write("Stai navigando a una risoluzione di "+screen.width+" x "+screen.height); } </script> </head> <body onLoad="apriFinestra();"> <a href="#" onClick="saluta();">clicca per ricevere un saluto</a> <br/><br/> <script type="text/javascript"> scriviRisoluzione(); </script> </body> </html> Nell’esempio che abbiamo esaminato or ora sono presenti tre funzioni, due delle quali vengono richiamate attraverso l’utilizzo di eventi, mentre la terza viene richiamata all’interno della pagina. Da notare inoltre che l’evento “onLoad” viene eseguito subito dopo il completamento della pagina, dunque una funzione richiamata all’interno del BODY della pagina verrà “lanciata” prima della funzione richiamata dall’evento onLoad. Nel nostro esempio la funzione “scriviRisoluzione()” viene lanciata prima della funzione “aprifinestra()”. È evidente che tramite un utilizzo oculato di funzioni ed eventi è possibile creare delle pagine molto ordinate, con il codice JavaScript suddiviso in molteplici parti, “azionato” soltanto quando richiamato. Nota a margine In realtà è possibile specificare che la funzione deve essere richiamata da un determinato evento direttamente dal codice JavaScript. Il codice è questo (da inserire nell’ <head>): <script type="text/javascript"> function saluta() { alert("ciao"); } // assegnamo il gestore saluta all'evento onload document.onload = saluta(); // la funzione viene lanciata non appena il documento è caricato // notare che "onload" è scritto tutto minuscolo </script> Come si vede nell’esempio il collegamento tra l’evento “onload” e la funzione “saluta” viene creato dalla stessa sintassi JavaScript, anziché essere specificato nel codice HTML. Dove utilizzare le funzioni I Prendiamo in considerazione questo esempio: <script type=”text/javascript”> scritta=”ciao”; function saluta() { alert(scritta); } saluta(); </script> in questo primo esempio una variabile viene creata e inizializzata al di fuori della funzione ed è poi richiamata all’interno della funzione stessa, senza che tutto ciò crei minimamente dei problemi. Esaminiamo un altro esempio: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <script type=”text/javascript”> function saluta() { //inizalizzo le variabili all’interno delle funzioni scritta2=”ciao”; scritta3=”prova scrittura” } saluta(); //richiamo la funzione alert(scritta2); //faccio riferimento alla variabile creata nella funzione </script> </head> <body > <script type=”text/javascript”> document.write(scritta3); </script> </body> </html> In questo esempio due variabili vengono create all’interno delle funzioni e richiamate poi dall’esterno: in un caso la variabile viene scritta addirittura in pagina senza che tutto ciò crei minimamente dei problemi. Molti linguaggi di programmazione creano una distinzione netta tra le variabili create all’interno del programma (nel nostro caso all’interno della pagina) e le variabili create all’interno delle funzioni. Le prime prendono il nome di variabili globali e sono valide in tutto il programma, le seconde vengono dette variabili locali e sono valide soltanto all’interno della funzione. Per indicare il contesto entro cui una variabile è valida si parla di solito di ambito delle variabili (in inglese “scope”). Per semplificare la vita del programmatore, in JavaScript questa distinzione è valida solo se espressamente richiesta dal programmatore stesso. Visto che questi sono i nostri primi programmi, possiamo evitare di distinguere tra variabili locali e variabili globali. Facciamo però attenzione a non incappare in due tipici errori: 1. Evitiamo di sovrascrivere le variabili nei nostri programmi. Ad esempio: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <SCRIPT type=”text/javascript”> function scriviNome() { // inizalizzo le variabili all’interno delle funzioni nome=prompt(“inserisci qui il tuo nome”,”il tuo nome”); } scriviNome(); // richiamo la funzione nome=”Gianni”; // in questo modo sovrascrivo la variabile </SCRIPT> </head> <body > <SCRIPT TYPE=”text/javascript”> document.write(nome); </SCRIPT> </body> </html> Nell’esempio, dato che la variabile “nome” viene inizializzata dopo la funzione, il contenuto della variabile creata nella funzione viene sovrascritto. 2. Ricordiamoci di utilizzare gli eventi nel modo appropriato: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <script type=”text/javascript”> function scriviNome() { //inizalizzo le variabili all’interno delle funzioni nome=prompt(“inserisci qui il tuo nome”,”il tuo nome”); } </script> </head> <body onLoad=”scriviNome()”> <script type=”text/javascript”> document.write(nome); </script> </body> </html> In questo caso siamo incappati un errore grossolano: la variabile “nome” viene richiamata dal document.write (che si trova nel corpo della pagina) senza essere stata ancora creata, infatti l’evento onLoad (che richiama la funzione che crea la variabile) viene lanciato dopo il completamento della pagina. Dove utilizzare le funzioni II Abbiamo visto che, se vogliamo, possiamo fare a meno di distinguere tra variabili globali (quelle valide in tutta la pagina) e variabili locali (quelle valide solamente all’interno delle funzioni). Qualche lettore esperto, può però trovarsi più a suo agio mantenendo questa distinzione (gli altri lettori possono passare oltre senza troppe preoccupazioni). Per creare le variabili locali (valide solo nella funzione) è sufficiente premettere alla dichiarazione di variabile il prefisso var. Guardate cosa succede se modifichiamo l’esempio della lezione precedente con il prefisso var: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <script type=”text/javascript”> function saluta() { //inizializzo le variabili all’interno delle funzioni var scritta2 = “ciao”; // variabile locale var scritta3 = “prova scrittura”; //variabile locale } saluta(); //richiamo la funzione alert(scritta2); //faccio riferimento alla variabile creata nella funzione </script> </head> <body > <SCRIPT TYPE=”text/javascript”> document.write(scritta3); </SCRIPT> </body> </html> le variabili non vengono più “lette”, perché definite come “locali” all’interno della funzione. Dunque il motore di scripting della pagina si dimentica di queste variabili appena uscito dalla funzione. Un ulteriore esempio chiarirà tutto: <script type=”text/javascript”> scritta2=”ciao globale”; // variabile globale function saluta() { // inizializzo le variabili all’interno delle funzioni var scritta2=”ciao locale”; // variabile locale } // richiamo la funzione saluta(); // faccio riferimento alla variabile alert(scritta2); </script> Tra le due variabili “vince” la variabili globale, perché la variabile locale ha il suo ciclo di vita solo all’interno della funzione. Se utilizziamo variabili globali e variabili locali, le funzioni diventano una scatola chiusa, e il suo interno non vede nulla di quanto avviene al di fuori. Avremo quindi bisogno di strumenti per passare dei valori all’interno della funzione, e di altri strumenti per estrarre quello che abbiamo elaborato dentro la funzione stessa: li vedremo nelle prossime lezioni. Nota: per evitare problemi con variabili locali e variabili globali, semplicemente omettete “var” quando create delle variabili. I parametri delle funzioni In molti casi può essere utile passare dei “valori variabili” a una funzione, in modo da poterla utilizzare in molti contesti. In questo modo non siamo costretti a scrivere una funzione ogni volta che dobbiamo cambiare qualcosa: basta scrivere il codice una sola volta e individuare delle porzioni variabili. Facciamo un esempio concreto. C’è una pagina in cui vogliamo aprire tre differenti finestre di diverse dimensioni: • la prima di 300×290 e deve contenere un link a www.html.it • la seconda di 400×390 e deve contenere un link ad freeasp.html.it • la terza di 500×490 e deve contenere un link a free.php.html.it In questo caso non è necessario scrivere tre differenti funzioni: basta scrivere la funzione una volta sola, specificando che ci sono delle parti della funzione che variano. Queste parti variabili si chiamano argomenti o parametri e vanno espresse nella dichiarazione della funzione. Così: function nomeFunzione(arg1, arg2, arg3, arg4) { //codice } I parametri vengono indicati all’interno del codice nel punto che ci occorre, e svolgono a tutti gli effetti il ruolo di variabili. Nella chiamata alla funzione dovremo poi indicare il valore che i parametri assumono nel caso specifico. Ad esempio: nomeFunzione(“finestraFreeAsp”,1 , 400, 390, “http://freeasp.html.it”); Gli argomenti sono quindi una specie di “ponte” tra l’interno e l’esterno della funzione. Vediamo un esempio semplice che ci permetta di afferrare subito il concetto: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Esempio</title> <script type=”text/javascript”> function saluta(nome) { //nome è l’argomento alert(“ciao “+nome); } </script> </head> <body> <a href=”#” onClick=”saluta(‘Saibal’)”>Saluta Saibal</a><br/> <a href=”#” onClick=”saluta(‘Phantom’)”>Saluta Phantom</a><br/> <a href=”#” onClick=”saluta(‘Berenicebis’)”>Saluta Berenicebis</a><br/> </body> </html> Come si vede nell’esempio la funzione è sempre la stessa, ma c’è un “punto” che cambia: quel “punto variabile” è l’argomento che viene indicato nella dichiarazione della funzione, cioè qui: function saluta(nome) per poi essere applicato all’interno del codice al momento giusto. Cioè qui: alert(“ciao “+nome); Torniamo all’esempio delle finestre, e riprendiamo quanto visto in una lezione precedente: <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Esempio</title> <script type=”text/javascript”> /* nella funzione sottostante passiamo 4 argomenti: il nome della finestra è necessario per aprire differenti finestre e non sempre la stessa */ function apriFinestra(nomeFinestra,larghezza,altezza,collegamento) { /*assegno alla variabile il valore dell’argomento*/ larghFinestra=larghezza; /* assegno alla variabile il valore dell’argomento*/ altezFinestra=altezza; sinistra=screen.width-larghFinestra+20; alto=(screen.height-larghFinestra)/2; /*gli ultimi due argomenti sono nella stringa sottostante */ window.open(collegamento,nomeFinestra,”left=”+sinistra+”,top=”+alto+”,width=” +larghFinestra+”,height=”+altezFinestra+”,menubar,toolbar,resizable”); //NB la riga precedente non va a capo } </SCRIPT> </head> <body> <a href=”#” onClick=”apriFinestra(‘finestraHTML’,300,290,’http://www.html.it’)”>HTML.it</a><br/> <a href=”#” onClick=”apriFinestra(‘finestraASP’,400,390,’http://freeasp.html.it’)”>FREEASP</a><br/> <a href=”#” onClick=”apriFinestra(‘finestraPHP’,500,490,’http://freephp.html.it’)”>FREEPHP</a><br/> </body> </html> come si vede la funzione che apre la finestra è sempre la medesima, cambiano invece le dimensioni, il nome della finestra e il link: tutto questo viene passato alla funzione come argomento. Restituire i valori di una funzione Abbiamo visto che se utilizziamo un approccio rigoroso con variabili globali e locali (quelle create con var) le funzioni diventano una scatola chiusa, e tutto quello che succede all’interno di una funzione non ha nessuna validità al di fuori. Ma come fare per comunicare con l’esterno? Se dobbiamo introdurre dei valori all’interno della funzione possiamo utilizzare gli argomenti, ma finora non abbiamo visto ancora nulla che ci permetta di restituire all’esterno dei valori. Vediamo un esempio. Per comodità decidiamo di inserire in una funzione il prompt con la richiesta di nome (che abbiamo esaminato in una precedente lezione) e decidiamo di utilizzare la dichiarazione di variabili locali. <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <script type=”text/javascript”> function chiediNome() { var nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”); //ATTENZIONE! //la variabile è definita come “locale” //se non mettessimo “var” funzionerebbe tutto } </script> </head> <body> <script type=”text/javascript”> chiediNome(); // lancio la funzione document.write(“Benvenuto “); document.write(nomeUtente); </script> </body> </html> Come si vede lo script che abbiamo composto dà errore, semplicemente perché la variabile è preceduta da var e quindi definita come locale: il browser (o più esattamente il motore di scripting del browser) si scorda della variabile appena fuori dalla funzione. Per risolvere questo problema dobbiamo utilizzare l’istruzione return, che serve per restituire i valori e fa sì che una funzione comunichi con l’esterno. Il return va messo sempre alla fine della porzione di codice che ci interessa, e si utilizza in due modi: return seguito da una variabile (o da un’espressione) return da solo restituisce il valore della variabile (o dell’espressione) fa terminare la porzione di codice Basta poi catturare tutta quanta la funzione in una variabile, per aver catturato il valore restituito dalla funzione stessa. Così: miaVariabile = miaFunzione(); Vediamo l’esempio precedente adattato con l’uso di return. <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>Corso JavaScript ad esempi</title> <script type=”text/javascript”> function chiediNome() { var nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”); return nomeUtente; //la funzione restituisce ora il nome dell’utente } </script> </head> <body> <script type=”text/javascript”> valoreCatturato=chiediNome(); // lancio la funzione document.write(“Benvenuto “); document.write(valoreCatturato); </script> </body> </html> In JavaScript per lo più utilizzerete un approccio “soft” alle variabili, e spesso non distinguerete tra variabili globali e locali, quindi non vi capiterà spesso di usare return. Infatti per avere a disposizione nel resto della pagina un valore creato all’interno di una funzione, basta crearlo senza usare var. Tutto funziona alla perfezione se scriviamo: function chiediNome() { nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”); } chiediNome(); alert(nomeUtente); Come abbiamo visto però, il return serve anche per bloccare l’esecuzione del codice e ci sono particolari contesti in cui può tornare particolarmente utile: lo vedremo nelle prossime lezioni. Vediamo comunque un esempio per afferrare subito il concetto: function saluta() { alert(“primo ciao”); return; alert(“secondo ciao”); } saluta(); come si vede il secondo alert non viene eseguito, perché posto dopo il return. Nota Bene A scanso di equivoci, è opportuno specificare che né gli argomenti, né il return sono obbligatori: in molti casi avremo funzioni che non hanno bisogno di nessun argomento, e che non restituiscono alcunché. Verificare una condizione: if Il codice che abbiamo utilizzato fino a questa lezione è molto semplice: si è sempre trattato di lavorare con le finestre, inserire dati in variabili e al massimo abbiamo sommato delle stringhe. Se la programmazione fosse soltanto questo, avremmo la possibilità di compiere ben poche operazioni. In realtà programmare è qualcosa di più complesso, dal momento che siamo in grado di porre delle condizioni, impostare delle ripetizioni, e altro. Possiamo ad esempio volere che il programma che stiamo scrivendo faccia qualche cosa soltanto a una determinata condizione (ad esempio solo nel caso in cui il browser dell’utente sia Internet Explorer). Potremmo schematizzare così: • se una determinata condizione è verificata… • fai questo Più esattamente si tratta di prendere una determinata condizione, valutarla, e se è vera (cioè se restituisce true), verranno eseguite le istruzioni indicate. Se la condizione non si verifica non verrà fatto alcunché. Ecco una rappresentazione grafica di quello che abbiamo appena detto: Figura 1. Diagramma di flusso Ed ecco il modo in cui JavaScript (in maniera del tutto analoga al C) esprime questo costrutto: if (espressione da verificare) { //istruzioni } La struttura della sintassi è chiara: la condizione da verificare viene indicata tra le parentesi tonde che seguono l’if (in inglese “se”, appunto). Notare le parentesi graffe, che racchiudono il codice da eseguire nel caso in cui la condizione sia valida. È bene inoltre ricordare, che ogni istruzione deve essere seguita dal punto e virgola. Per afferrare subito la sintassi per un po’ vedremo alcuni semplici esempi numerici. Non appena saremo padroni dei concetti torneremo ad esaminare esempi pratici, inerenti il webpublishing. Vediamo un esempio di if: x = 5; // sostituite x con quello che volete if (x == 5) { alert(“la variabile x è uguale a 5″); } L’espressione (x == 5) risulta vera, dal momento che la variabile è stata creata appositamente con il valore richiesto dalla condizione (ma d’ora in poi provate a sostituire il valore della variabile creata all’inizio degli esempi per vedere i differenti risultati degli script). Infatti se invece abbiamo: x = 6; if (x == 5) { alert(“la variabile x è uguale a 5″); } L’espressione dell’esempio viene valuta, ma dal momento che non è vera l’alert non viene visualizzato. Negli esempi appena esaminati, abbiamo incontrato per la prima volta l’operatore di uguaglianza, cioè ==, che ci permette di verificare che le variabili (o le espressioni) a sinistra e a destra dell’uguale abbiano lo stesso valore. Nota a margine Le parentesi graffe sono necessarie soltanto nel caso in cui le istruzioni da eseguire siano più di una, altrimenti possono essere anche omesse. Infatti le parentesi graffe indicano sempre l’esistenza di un blocco di istruzioni (le abbiamo già incontrate nelle funzioni con la medesima funzione). Ad esempio: x=5; if (x==5) alert(“la variabile x è uguale a 5″); o anche tutto su una riga: x=5; if (x==5) alert(“la variabile x è uguale a 5″); mettere le parentesi graffe in presenza di una sola istruzione tuttavia non costituisce errore e di solito conferisce una maggior leggibilità al codice. Operatori relazionali Nella lezione precedente abbiamo introdotto il concetto intuitivo di “condizione da valutare”. In realtà si tratta più esattamente di valutare che la relazione tra due valori (o espressioni) sia vera. Nella lezione precedente abbiamo introdotto il concetto intuitivo di “condizione da valutare”. In realtà si tratta più esattamente di valutare che la relazione tra due valori (o espressioni) sia vera. <valore> <operatore di relazione> <valore> Ad esempio: x == 5 Ed ecco gli altri operatori: Operatore > >= < Spiegazione maggiore maggiore uguale minore Esempio x>7 x>=7 x<7 <= minore uguale x<=7 == uguale nome==”Mario” != diverso Nome!=”mario” Un errore tipico dei principianti è quello di confondere l’operatore di uguaglianza, con il doppio simbolo “=” (==) con l’operatore di assegnamento (=). Ad esempio questo: x=8; if (x=5) { //dovrebbe essere ==, non = alert(“la variabile x è uguale a 5″); } risulterà sempre vero, perché all’interno delle parentesi viene assegnato un valore, e non viene invece eseguito un confronto. Inserire la relazione tra due valori in un alert è un metodo sbrigativo per sapere se la relazione è vera oppure no: x = 5; alert(x >= 5); alert(x < 5); Finora abbiamo sempre assegnato il valore delle variabili all’interno della pagina: tuttavia non si tratta di un procedimento molto utile, dal momento che la possibilità di valutare la veridicità di un espressione ci interessa soprattutto quando non conosciamo i valori delle variabili. Ci interessa sapere ad esempio se: variabileUtente == variabileImpostataDaMe; oppure variabileAmbiente == variabileImpostataDaMe; negli esempi delle prossime lezioni vedremo come “catturare” questi valori Come funzionano else ed else if Abbiamo visto che è possibile fare eseguire un’azione se una condizione è vera. Ma se volessimo far eseguire un’altra azione nel caso in cui la condizione sia falsa? Possiamo allora impostare un programma di questo tipo: • se una determinata condizione è verificata… fai questo • in tutti gli altri casi… fai quest’altro Possiamo esprimere graficamente questo concetto con i diagrammi di flusso: Figura 1. Diagramma di flusso II e traducendolo in codice JavaScript: if (condizione) { // istruzione 1 } else { // istruzione 2 } Ad esempio: x = 9; if (x < 7) { alert(“x è minore di 7″); } else { alert(“x non è minore di 7″); } Con una sintassi analoga si possono anche verificare l’esistenza di diverse condizioni. Si tratta di impostare un programma di questo genere: • se si verifica questa condizione… fai questo • altrimenti, se si verifica quest’altra condizione… fai quest’altro • in tutti gli altri casi… fai quest’altro che graficamente si può rappresentare così: Figura 2. Diagramma di flusso III Per esprimere l’else if, JavaScipt prevede una sintassi di questo genere: if (prima condizione) { //istruzioni } else if (seconda condizione) { //istruzioni } else { //istruzioni } Ed ecco un esempio: nome=”Gianni”; if (nome==”Mario”) { alert(“ciao Mario”); } else if (nome==”Gianni”) { alert(“ciao Gianni”); } else { prompt (“identificati”,”inserisci il tuo nome”); } È possibile anche introdurre più di un else if all’interno dello stesso blocco di codice; è dunque possibile verificare quante condizioni si desidera. Esempio: individuare il browser Abbiamo visto, quando abbiamo parlato del DOM che la difficoltà maggiore della programmazione JavaScript consiste nel fatto che a browser differenti corrispondono differenti modelli di documenti. JavaScript ci consente di verificare in un modo molto semplice se una proprietà di un oggetto esiste oppure no, è sufficiente utilizzare la sintassi: if (nomeOggetto.nomeProprietà) { //istruzioni } se la proprietà esiste, nomeOggetto.nomeProprietà restituisce true e quindi la condizioni è verificata (e dunque le istruzioni vengono eseguite). Se la proprietà non esiste nomeOggetto.nomeProprietà restituisce false, e quindi la condizione non è verificata. Questo accorgimento ci è molto utile nei molti casi in cui vogliamo adattare la pagina a seconda del browser: ad esempio per spedire un foglio di stile differente a seconda del browser usato. Abbiamo detto che internet Explorer (qualsiasi versione) viene identificato da document.all, Netscape da document.layers, i browser di nuova generazione da document.getElmentById. Per individuare il browser e far eseguire un codice differente a seconda del risultato, dovete allora impostare un programma di questo genere: • se è presente document.all codice da eseguire (se entriamo in questa casistica, i successivi else if ed else non vengono neanche valutati) • se invece è presente document.layers codice da eseguire • se è presente document.getElementById codice da eseguire • in tutti gli altri casi codice da eseguire Traducendo quanto appena detto in codice JavaScript: if (document.all) { alert(“stai usando Internet Explorer”); } else if (document.layers) { alert(“stai usando Netscape 4″); } else if (document.getElementById) { alert(“stai usando Netscape 6, o un browser di nuova generazione”); } else { prompt (“stai usando un browser sconosciuto”); } Attenzione però alle “proprietà mimetiche” di Opera, che è in grado di camuffarsi da Internet Explorer o da Netscape. Se volete approfondire l’argomento, e vedere come spedire un differente foglio di stile esterno a seconda del browser potete consultare due articoli su html.it: L`arte dello sniffing: come riconoscere i browser e Riconosciamo i browser con Javascript. Gli operatori logici È possibile annidare un if dentro l’altro, in modo da poter valutare anche situazioni particolarmente complesse. Ad esempio: // provate a cambiare il valore, eventualmente // indicando anche delle stringhe valore = 5; if (isNaN(valore) ) { /* isNaN() vuol dire "not a number" e serve per * vedere se il tipo di dati in esame è differente * da un numero */ alert(valore + " non è un numero!"); } else { } if (valore >= 9) { alert(valore + " è maggiore o uguale a 9") } else { alert(valore + " è minore di 9") } Ma oltre ad utilizzare annidamenti particolarmente complessi, possiamo usare gli operatori logici per concatenare diverse espressioni e creare condizioni complesse. La sintassi è questa: ( (<espressione 1>) <operatore logico> (<espressione 2>) ) dove (come abbiamo visto nelle precedenti lezioni) <espressione 1> ed <espressione 2> stanno per: <valore1> <operatore relazionale> <valore 2> Ad esempio: x = 6; if ( (x >= 5) && (x <= 7) ) { alert ("x è compresa tra 5 e 7"); } In questo modo possiamo valutare più condizioni contemporaneamente. Gli operatori logici che utilizzerete maggiormente sono i seguenti: Operatore && || Descrizione “and logico” Devono essere vere le espressioni a destra e sinistra dell’uguale. Esempio x=6; if ( (x>=5) && (x<=7) ){ alert (“x è compresa tra 5 e 7″); } nome=”Gianni”; if ( (nome==”Gianni”) || “or logico” (nome==”Marco”) ) { Deve essere l’espressione a sinistra dell’uguale o alert (“Sei Gianni oppure Marco”); quella a destra } “not” Viene posta di fronte all’espressione in questione ! e la nega: - se è false la cambia in true - se è true la cambia in false Gli operatori logici funzionano nel modo seguente: nome=”Marco”; if ( !(nome==”Marco”)) { alert (“Non sei Marco”); } • viene esaminata l’espressione di sinistra (Questo significa che anche tutte le operazioni previste dall’espressione di sinistra sono eseguite prima) • se l’operatore è binario (“and” e “or” ad esempio) si passa ad esaminare l’espressione di destra. Nota: Se l’espressione di sinistra è sufficiente a determinare il risultato dell’operazione, quella di destra viene ignorata. Ad esempio: se l’operando è un or (||) e l’espressione di sinistra genera un true, non è necessario valutare anche l’espressione destra, perché il risultato sarà comunque true, se abbiamo un and (&&) invece, sarà ignorata l’espressione destra se a sinistra abbiamo già un false. • viene restituito il risultato Avrete notato che la rappresentazione grafica di un operatore logico prevede il raddoppiamento del simbolo corrispondente (es: &&). Nel caso in cui vi dimentichiate di raddoppiare il simbolo (es: &), state in realtà utilizzando un operatore a livello di bit: il che non è scorretto, ma non sempre darà luogo allo stesso risultato. Uso del “not” e operatori di bit Una menzione particolare la merita l’operatore di negazione(indicato con !), che serve a negare un’espressione. Si tratta di un operatore unario: viene infatti posto di fronte all’espressione da negare, senza essere confrontato con nient’altro. Utilizzando l’operatore di diversità nel giusto modo possiamo scrivere: • se la condizione è falsa… • fai questo La sintassi è la seguente: if ( ! (espressione) ) { //istruzioni } che significa: • se nego l’espressione e così facendo ho un risultato vero… • allora fai questo Ad esempio: x = 7; if (! (x == 7) ) { alert (“x non è 7″); } Ovviamente l’esempio che abbiamo appena esaminato non è di particolare utilità e in questo caso non c’è una grossa differenza rispetto all’utilizzo dell’operatore di diversità (!=) che abbiamo visto nelle lezioni precedenti: x = 7; if (x! = 7) { alert (“x non è 7″); } Ma se teniamo conto che possiamo utilizzare gli operatori logici per creare situazioni molto complesse, combinando fra loro le varie espressioni, allora appare evidente come l’utilizzo del not sia particolarmente utile. Ad esempio: nome=”Gianni”; if ( ! ( (nome == “Gianni”) || (nome == “Marco”) ) ) { alert (“Non sei né Gianni, né Marco”); } Nota a margine Abbiamo accennato nella lezione precedente agli “operatori a livello di bit”. Nella programmazione JavaScript non li userete quasi mai, ma è bene sapere che esistono. Perché se per errore scrivete: (x >= 5) & (x <= 7) in realtà state utilizzando un operatore a livello di bit e non un operatore logico. La differenza sta nel fatto che gli operatore di bit convertono tutte le espressioni in valori binari, prima di eseguire i confronti, e poi li confrontano bit a bit. Dal momento che – a volte – ciò comporta delle approssimazioni, la valutazione delle espressioni può non dare adito allo stesso risultato rispetto agli operatori logici. Operatore Spiegazione Esempio x=6; & “and a livello di bit” if ( (x>=5) & (x<=7) ) { alert (“x è compresa tra 5 e 7″); } nome=”Gianni”; | “or a livello di bit” if ( (nome==”Gianni”) | (nome==”Marco”) ) { alert (“Sei Gianni oppure Marco”); } nome=”Gianni”; ^ ~ if ( (nome==”Gianni”) ^ “or esclusivo a livello (nome==”Marco”) ) { di bit” alert (“Sei Gianni oppure Marco”); } “not a livello di bit” x=7; if (~ (x==7) ) { alert (“x non è 7”); } Vediamo un esempio in cui operatori logici e operatori a livello di bit danno adito a risultati differenti. Nell’esempio seguente l’operatore logico restituisce un risultato corretto: if ( (document.all) && (navigator.platform.indexOf(“Win”)>-1) ) { alert (“Stai usando Internet Explorer su Windows”); } else { alert (“Stai usando Internet Explorer su Mac”); } /* L’oggetto navigator.platform contiene le indicazioni sul sistema operativo che l’utente sta usando. Nel caso di Windows: alert(navigator.platform); restituisce “Win32″ indexOf serve per cercare del testo in una stringa: se non lo trova restituisce “-1″, ecco perché abbiamo chiesto di verificare che il risultato di indexOf sia maggiore di -1. In pratica così facendo abbiamo chiesto di verificare che navigator.platform contenga “Win”. */ Utilizzando l’operatore a livello di bit invece il risultato dello script non è corretto: if ( (document.all) & (navigator.platform.indexOf(“Win”)!=-1) ) { alert (“Stai usando Internet Explorer su Windows”); } else { alert (“Stai usando Internet Explorer su Mac”); }