LEZIONI DI PROGRAMMAZIONE PER IL WEB

 

 

 

back to HomePage   

 

 

QUESTO DOCUMENTO E' IN VIA DI COMPLETAMENTO ENTRO GENNAIO 2016

CI SCUSIAMO CON I VISITATORI PER LA MANCANZA DI MOLTI CONTENUTI CHE PRESTO VI APPARIRANNO

 

 

INDICE

 

 

generali

  Note per la lettura di questo documento

  Dove posso trovare documentazione online sui linguaggi php, javascript e html?

  Come posso ottenere una perfetta copia pdf di una pagina internet che contiene un articolo di web design che mi interessa?

  Esistono libri consigliabili a chi si avvicina per la prima volta a php, ajax, mySQL?

 

siti internet in hosting gratuito (es. altervista.org)

  Utilizzare un hosting gratuito per disporre di un server php che consenta di sperimentare il linguaggio e le sue potenzialità

  Cos'è un programma FTP? Qual è il miglior programma FTP scaricabile gratuitamente consigliato in alternativa a quello di altervista.org?

 

html & css

  Come funziona un browser

  La dichiarazione DOCTYPE

  Visualizzare il codice di una pagina web

  Gli elementi della pagina web

  Come centrare orizzontalmente e verticalmente un elemento nella pagina web

  Come si crea e si configura una tabella con i fogli di stile

 

javascript & jquery

  I malfunzionamenti più gravi di Explorer di cui il programmatore javascript dovrebbe essere a conoscenza

  Come rilevare le versioni di Explorer e in particolare quelle anteriori a Explorer 9

  Cos'è javascript

  Cos'è jQuery

  Cos'è il DOM che viene utilizzato da javascript?

  Acquisire e manipolare gli elementi di una pagina tramite javascript e jQuery

  Come si costruisce un oggetto javascript

  Racchiudere un contenuto troppo grande per lo spazio assegnato nella pagina entro un box con barre di scorrimento verticali e orizzontali

  La proprietà documentElement

  Subordinare l'apertura di un link al valore vero/falso di una funzione javascript

  Tracciare la posizione relativa e assoluta del mouse entro la finestra, indipendentemente dallo scrolling

  Acquisire la posizione di un elemento entro il documento

  Fare lo scrolling fino a portare un elemento della pagina in vista

  Dotare una pagina web di ToolTip (box informativi che appaiono quando il mouse passa sopra ad un elemento)

  Inserire nel campo "title" dei vostri link, al caricamento della pagina, informazioni che verranno visualizzate dal browser al passaggio del mouse, utilizzando XML, javascript e php

  Alcune cose che javascript non fa o fa solo a prezzo di una programmazione complicata e poco pulita

 

php & mysql

  Una pagina php che cambia aspetto ogni volta che la si ricarica

  Un codice php per consentire agli utenti del vostro sito il download di qualsiasi tipo di file

  Una pagina in cui una routine php genera una tabella che mostra il contenuto di un database

  Come importare una tabella Access nel database MySQL del vostro server, utilizzando XML e php

  Alcune cose che php non fa, anche se sembrerebbe possibile

 

ajax

  Introduzione ad ajax

  Inviare dati al server tramite i metodi GET e POST e gestirli con una routine php

  Acquisire un documento XML dal server e metterlo a disposizione di javascript

  Acquisire codice javascript dal server ed eseguirlo immediatamente tramite la funzione eval()

  Creare un oggetto javascript che incorpori una pagina html esterna e manipolarla

  Come ottenere l'esatto indirizzo di una pagina internet che si vuole utilizzare con javascript

  Una pagina per sperimentare semplice codice javascript, jQuery, ajax, php

  Alcune cose che con ajax non si possono fare, anche se apparentemente sembrerebbero semplici

 

xml & xpath & simplexml

  Cos'è un documento XML e come lo si può gestire

  Leggere un documento XML posto sul server e farne apparire il contenuto nella pagina web

 

varie

  Suggerimenti vari

  Argomenti vari

 

 

 

 

 

 

Note per la lettura di questo documento

back to Index

 

 

Come già detto, questo documento è in via di completamento entro gennaio 2016. Controllate quindi, dopo questa data, se siano presenti altri articoli di vostro interesse.

 

Controllate alla fine di ogni articolo se sono presenti riferimenti a risorse internet che potrebbero esservi utili riguardo l'argomento ("ulteriore documentazione consultabile").

 

Se viene riportato un codice di più righe con una riga colorata:

 

<style type ="text/css">

 .TableCell {

  border : 1px solid black;

  text-align : center;

  padding : 10px;

 }

</style>

 

se la riga viene riportate e commentata singolarmente più in basso, essa avrà lo stesso colore, per facilitare la sua identificazione nel codice:

 

border : 1px solid black;

 

All'interno di un articolo eventuali sottotitoli in rosso:

 

ulteriore documentazione consultabile

 

servono ad illustrare la ripartizione dei contenuti.

 

 

 

Dove posso trovare documentazione sui linguaggi php, javascript e html?

back to Index

 

 

  Google è una delle principali fonti di informazione: è sufficiente premettere nel box di ricerca il nome del linguaggio e scrivere del problema (ad esempio: "php string functions"): appariranno subito le ricerche pertinenti il nostro caso che sono state fatte da altri programmatori. Questo è il sistema più comunemente usato da molti sviluppatori.

Un consiglio: chi conosce bene l'inglese dovrebbe digitare i suoi quesiti in questa lingua, perché le risorse internet in lingua anglosassone sono molto più complete e approfondite di quelle in lingua italiana.

  Il sito W3schools.com (in lingua inglese) offre pagine chiare e corredate di esercizi pratici su javascript, php, html

  Il sito stackoverflow.com (in lingua inglese) non è personalmente quel che consiglierei per acquisire i rudimenti, perché riporta semplicemente domande e risposte di programmatori, con poche righe di esplicazione. Molti post sono inutili o poco comprensibili. Ma con pazienza si possono trovare soluzioni interessanti a problemi particolari.

  Il forum del sito altervista.org fornisce molte utili risposte a problemi di programmazione riguardanti siti gestiti con php e MySQL

  www.developer.mozilla.org (inglese) contiene numerosi esempi e soluzioni scritte e indirizzate a sviluppatori in ambito Firefox, ma normalmente anche con gli altri browser

  Controllate alla fine di ogni articolo di questo documento se sono presenti riferimenti a risorse internet che potrebbero esservi utili riguardo l'argomento ("ulteriore documentazione consultabile").

 

 

 

Come posso ottenere una perfetta copia pdf di una pagina internet che contiene un articolo di web design che mi interessa?

back to Index

 

 

Sarà capitato a tutti di imbattersi in un interessantissimo articolo di programmazione, e di non avere il tempo di esaminarlo sul momento. Come salvarlo per poterlo poi rileggere in tutta calma?

L'opzione "Salva pagina con nome"   "Solo HTML" rende necessario ricollegarsi ad internet (e nel frattempo la pagina potrebbe essere stata tolta o cambiata…)

L'opzione "Salva pagina con nome"   "Pagina web completa" riproduce sul vostro computer la pagina intera, ma il download è lento e il file è ingombrante.

Google Chrome mette a disposizione una funzionalità incredibilmente utile, che non è posseduta dagli altri browser: la possibilità di creare in pochi secondi una perfetta copia pdf di qualsiasi pagina.

E' sufficiente selezionare dal menu la voce "stampa", cliccare sul bottone "modifica" e selezionare, invece di una stampante, l'opzione "Salva come PDF".

Chrome, invece di procedere alla stampa chiederà dove salvare il documento PDF, che potrete aprire tranquillamente in seguito.

 

 

 

Esistono libri consigliabili a chi si avvicina per la prima volta a php, ajax, mySQL?

back to Index

 

 

Una premessa importante: i libri in lingua inglese sono spesso indispensabili, per completezza e per chiarezza che purtroppo mancano a non pochi libri italiani. Oltre a ciò, il loro prezzo è decisamente più contenuto di questi ultimi. Moltissimi testi inglesi sono disponibili in ebook, il che ne abbassa ulteriormente il costo. Quasi tutti forniscono un indirizzo internet da cui scaricare le pagine con il codice già scritto.

Ecco, senza alcuna pretesa di esaustività, un elenco di libri che sono stati utilissimi a chi scrive e sufficienti a fargli apprendere come creare e gestire il suo sito internet:

 

  Lemay-Colburn, HTML & CSS, McGraw-Hill

  Beighley,  jQuery for Dummies, Wiley Publishing Inc.

Libro in lingua inglese. Disponibile versione ebook

  Holzner,  Ajax: A Beginner's Guide, McGraw-Hill

Libro in lingua inglese. Disponibile versione ebook

Libro assolutamente consigliabile: contiene una descrizione passo-passo di XML, javascript e DOM, ajax, php. Il codice è commentato riga per riga e niente è lasciato senza spiegazione. Viene fornito un link per scaricare tutti i file di esempio.

  Nixon, Learning PHP, MySQL, JavaScript, and CSS: A Step-by-Step Guide to Creating Dynamic Websites, O'Reilly.

Libro in lingua inglese. Disponibile versione ebook

  Amedeo, JQuery, Apogeo Pocket

  Rubini, MySQL versione 5, Apogeo Pocket

  Rubini, Javascript, Apogeo Pocket

  Canducci, PHP 5, Apogeo Pocket

  Flanagan, Javascript Pocket Reference, Tecniche Nuove-O'Reilly

  Ferrero, SQL, Apogeo Pocket

  Powers, Programmare in Javascript, Tecniche Nuove-O'Reilly

Contiene anche una trattazione di ajax

  Meyer, Cascading Style Sheets, Tecniche Nuove-O'Reilly

  Bodensiek, Effetti speciali per il web, Jackson Libri

  Schafer, HTML e CSS, Mondadori

  Kofler, MySQL5, Guida completa, Apogeo

  Nikolassy, Manuale di Javascript, Hoepli

Libro validissimo, completo e letteralmente infarcito di codice e di esercizi.

 

Tutti i libri Apogeo sono disponibili in versione ebook. Molti sono libri pocket, economici ma completi per un apprendimento di medio livello.

Personalmente, tra gli editori italiani, chi scrive si è trovato bene con Apogeo, Mondadori e McGraw-Hill, mentre considera Jackson Libri di qualità inferiore e talvolta alquanto scadente.

 

 

 

Utilizzare un hosting gratuito per disporre di un server php che consenta di sperimentare il linguaggio e le sue potenzialità

back to Index

 

 

Il sito www.altervista.org è uno dei siti di hosting gratuiti europei più importanti. Mette a disposizione degli utenti un nome di dominio e uno spazio sul server di 2 Gb, con un traffico di 30 Gb al mese, 20mila query all'ora per il database mySQL.

Tra i linguaggi che vengono supportati dai suoi server c'è php versione 5, MySQL versione 5, un programma FTP per fare l'upload e il download dei files sul server.

Il database MySQL è gestibile in modo semplicissimo con codice php e dal proprio account altervista tramite PhpMyAdmin, un programma open source di gestione del database che consente di creare tabelle e collegamenti e fare delle query.

Anche www.xoom.virgilio.it è un hosting gratuito di buon livello, dotato di php, MySQL e di spazio illimitato su server

 

 

 

Cos'è un programma FTP? Qual è il miglior programma FTP scaricabile gratuitamente in alternativa a quello di altervista.org?

back to Index

 

 

Un programma FTP, tipicamente, consente di effettuare l'upload e il download di files (pagine web, files di testo o di altro tipo) dall'hard-disk del proprio computer al server che ospita il proprio sito e viceversa.

Uno dei migliori programmi scaricabili gratuitamente è senz'altro Filezilla di SourceForge. Per semplicità d'uso e di interfaccia e per completezza di funzionalità è semplicemente insuperato per gli utenti alle prime armi, ma anche per quelli esperti è estremamente potente.

 

 

 

Come  funziona un browser

back to Index

 

 

L'utente digita un URL (acronimo di "Uniform Resource Locator"), cioè l'indirizzo di una pagina web nella barra degli indirizzi del browser, come ad esempio: "http://www.server.com".

Il browser cerca l'IP corrispondente a quell'URL. Ogni computer collegato ad internet ha un indirizzo IP ("Internet Protocol address"), incluso il vostro (esistono anche altri significati di IP che non vanno confusi con questo: "Internet Provider", è ad esempio la società che vi fornisce l'accesso ad internet). Il browser consulta il DNS ("Domain Name Service") per trovare l'indirizzo IP del server associato a "server.com".

Il browser, utilizzando l'IP address, invia una richiesta al server corrispondente a quell'indirizzo, di inviare l'home page.

Il server, ricevuta la richiesta, cerca la home page sul suo hard disk. I server web sono configurati in modo da inviare una pagina di default (il file-indice) ogni volta che un browser richiede un nome di directory. Per esempio, se il vostro link è "www.example.com/about/", un tipico server web cercherà in quella directory un file chiamato "index.html". I nomi più comuni, sono "index.htm", "index.html", "index.php", "index.asp". Moltissimi indirizzi ufficiali internet forniti da società o siti, come: "www.usatoday.com" o "www.flowersgallery.com" sono solo indirizzi di directory all'interno delle quali si trova la pagina di default, non di rado annidato in sottodirectory. Molti server impediscono al browser di visualizzare nella barra degli indirizzi il nome del file-indice.

Se il server si accorge che nella pagina è incorporato del codice server-side come php, lo esegue prima di inviare la pagina web (es. si collega ad un database per recuperare dei dati da mostrare nella pagina; configura elementi della pagina in base al tipo di utente che ha fatto la richiesta; ecc.).

Il server invia la pagina al browser.

Il browser mostra la pagina sul vostro computer.

Normalmente questo processo si ripete per ogni elemento della pagina web: un grafico, un video, una pagina di stile CSS.

Se il browser si accorge che nella pagina è incorporato del codice client-side (tipicamente javascript) lo esegue immediatamente dopo il caricamento della pagina, a meno che si tratti di funzioni da attivare solo a seguito di un evento.

 

 

 

La  dichiarazione DOCTYPE

back to Index

 

 

E' importante porre, all'inizio del documento,  prima del tag <html>, la seguente dichiarazione:

<!DOCTYPE HTML>

che può scriversi anche in minuscolo:

<!doctype html>

Questo elemento della pagina dice al browser quale versione del linguaggio HTML è usata nel codice che segue. Senza questa indicazione, il browser è costretto ad indovinare a quale versione si riferiscano i comandi, e questo non è molto raccomandabile.

Commentiamo la seguente dichiarazione:

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

 

HTML : il linguaggio utilizzato è HTML

PUBLIC : il documento è pubblico; in alternativa viene dichiarato "SYSTEM" (il documento è una risorsa privata)

"-//W3C//DTD XHTML 1.0 Strict//EN" : si tratta di una DTD ("Document Type Declaration") in forma di FPI ("Formal Public Identifier"). In alternativa ad una DTD in forma di FPI si può usare una DTD in forma di URL del tipo: "http://www.w3.org/DTD/xhtml1.dtd".

Commentiamo qui sotto i singoli elementi della dichiarazione:

//W3C : il documento fa riferimento alle specifiche del consorzio W3C. Il segno meno (" - ") indica che le specifiche non sono registrate all'ISO (International Standardization Organization, Organizzazione di Standardizzazione Internazionale). Se lo fossero state ci sarebbe un " + "

//DTD XHTML 1.0 Strict : la definizione vera e propria del tipo di documento (DTD). Il linguaggio XHTML è l'immediato successore del linguaggio HTML 4.1, e ha due versioni: "XHTML transitional", che è maggiormente compatibile con il vecchio HTML 4.1 e "XHTML strict", che contiene diverse caratteristiche incompatibili con HTML 4.1.

//EN : la lingua in cui è scritta la DTD è l'inglese

Con l'avvento di HTML5 non è più necessaria una DTD in forma di FPI o di URL, e la dichiarazione è semplicemente:

 

<!DOCTYPE HTML>

 

Ecco i vari tipi di dichiarazioni per i diversi linguaggi che si sono succeduti nel tempo:

 

Tipo di documento

Dichiarazione:

HTML5

<!DOCTYPE html>

XHTML 1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

XHTML 1.1 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XHTML 1.1 Transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

XHTML 1.1 Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

XHTML 1.0 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XHTML 1.0 Transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

XHTML 1.0 Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

HTML 4.01 Strict

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

HTML 4.01 Transitional

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

HTML 4.01 Frameset

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

HTML 3.2

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

HTML 2.0

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

 

HTML5, il linguaggio più comunemente utilizzato attualmente, è una evoluzione del linguaggio HTML che supporta tra l'altro anche elementi audio e video

 

ulteriore documentazione consultabile:

https://en.wikipedia.org/wiki/Document_type_declaration : Pagina Wikipedia che spiega come funziona una dichiarazione DOCTYPE (in inglese)

 

 

 

Visualizzare il codice di una pagina web

back to Index

 

 

Con Chrome, tasto destro del mouse, opzione "visualizza sorgente pagina"

Con Mozilla, tasto destro del mouse, opzione "visualizza sorgente pagina"

Con Explorer, tasto destro del mouse, opzione "HTML"

 

 

 

Gli elementi della pagina web

back to Index

 

 

Cominciamo col distinguere block-elements e inline-elements, distinzione che ci sarà utile nel prosieguo. Ogni elemento della pagina html ha un valore display che può essere modificato col foglio CSS, e il valore di default per molti elementi è block o inline.

Un block-level element inizia sempre con una nuova linea, è seguito da un'altra linea e si estende a sinistra e a destra quanto può (provate a settare il bordo con l'istruzione CSS: border : 1px solid black e vedrete che il box si estende per tutta la larghezza della pagina). Sono esempi di block-level elements:

 

<div>, <table>, <h1> … <h6>, <p>, <form>

 

Un block-element ha le seguenti caratteristiche:

 

   Si espande automaticamente entro il suo parent container

   Può avere margini o padding

   Se non è settata la proprietà width, o è settata ad auto si espande naturalmente ad incorporare gli elementi figli (es. dei paragrafi entro un <div>)

   Di default è posto al disotto degli altri elementi della pagina, nell'ordine stabilito entro il codice html o dal posizionamento assoluto

   Ignora la proprietà vertical-align

 

un inline element non inizia con una nuova linea e ha la larghezza strettamente necessaria. Ad esempio gli elementi:

 

<span>, <a>, <img>, <button>, <input>, <label>, <select>, <textarea>, </br>

 

sono inline elements. La maniera migliore di descrivere un simile elemento è di pensarlo come un box che si comporta come una stringa di testo.

Un inline element ha le seguenti caratteristiche:

 

   E' contenuto nell'eventuale testo del blocco, e non provoca al suo interno un ritorno a capo

   E' soggetto alle proprietà CSS white space

   Non accetta le proprietà top margin e bottom margin, ma accetta le proprietà padding, left margin, right margin

   Non accetta le proprietà width ed height

   Accetta la proprietà vertical-align

 

Consideriamo la seguente rappresentazione di un box in una pagina web:

 

 

Come si vede, qualsiasi box ha una area del contenuto, un margine, che segna l'area più esterna, un border, che individua il confine che può essere visualizzato come linea, un padding, cioè una distanza tra il border e il contenuto. Ciascuno di questi elementi (margin, border, padding) può essere trattato separatamente rispetto al lato destro (right segment), lato sinistro (left segment), lato superiore (top segment), lato inferiore (bottom segment), ma spesso è utile generare il padding o i margini o lo spessore del bordo sui 4 lati mediante istruzioni come:

 

margin : 5 px;

padding : 5px;

border : 5 px;

 

Il limite del margine si chiama outer edge o margin edge; il limite che segna la fine del bordo è il border edge; il limite dove cessa l'effetto del padding è il padding edge, e finalmente abbiamo l'inner edge o content edge, che circonda immediatamente il contenuto. Per ciascuno si ha un top edge, bottom edge, right edge, left edge.

I valori possono essere dati in percentuale, in pixel o settati come "auto".

E' possibile dare un valore negativo ai margini: questo vuol dire che gli altri contenuti web "entreranno" nel box invece di esserne distanziati (con il margine positivo)

Consideriamo ad esempio il seguente codice:

 

<div id="parent" style="margin-left:auto;margin-right:auto;text-align:center;border:1px solid black;width:400px;height:50px;line-height:auto;vertical-align:middle;padding:5px;">

 <div id="child" style="border:1px solid red;margin-left:auto;margin-right:auto;margin-bottom:-10px;height:30px;">

 </div>

 Questa è una linea di testo!

</div>

 

Esso genera la seguente immagine nella pagina web: il box nero delimita il div "parent", mentre il box rosso delimita il div "child", che ha un margine negativo di -10 pixels: si vede chiaramente che in tal caso la linea di testo "invade" lo spazio dell'elemento.

Le proprietà di larghezza del bordo per i vari lati sono espresse da border-top-width, border-bottom-width, border-left-width, border-right-width, che, anziché in pixels o percentuale, possono essere settati con i valori predefiniti thick, medium, thin.

Le proprietà di colore sono espresse da border-top-color, border-bottom-color, border-left-color, border-right-color.

Lo stile della linea del bordo viene settata normalmente a border : none, oppure a border : solid (a cui si aggiunge il colore)

Passiamo ora ad illustrare una proprietà importantissima di ogni elemento della pagina: position.

   static : è il valore di default; gli elementi vengono posizionati secondo l'ordine in cui appaiono nel codice della pagina web, uno dopo l'altro, verticalmente:

   relative : l'elemento viene posizionato relativamente alla sua posizione static, precisando l'offset rispetto ad essa:

Il codice CSS corrispondente alla disposizione visualizzata sopra è il seguente:

 

#box-1 {
width: 150px;
}

#box-2 {
width: 150px;
position: relative;
left: 10px;
top: 10px; 
}

#box-3 {
width: 150px;
}

 

   absolute : posiziona l'elemento rispetto al documento, con le istruzioni:

 

position: absolute;
right: 10px;
bottom: 10px;

 

   fixed : posiziona l'elemento rispetto alla finestra. Questo vuol dire che lo scrolling non sposta l'elemento, come invece fa nel caso di position absolute:

 

position: fixed;
top: 0px;

 

Qualsiasi contenuto della pagina, secondo le specifiche CSS, è racchiuso in un rettangolo chiamato CSS box. Nel caso di block-elements come <div> è l'elemento stesso a formare il rettangolo, chiamato block box. Ma nel caso di un inline element e contiene un testo lungo, richiede più rettangoli per essere mostrato. Questi rettangoli sono chiamati anonymous boxes. Si vede così che i contenuti di un elemento possono consistere di un solo rettangolo o di rettangoli multipli. E' possibile acquisire tutti questi rettangoli con la funzione element.getClientRects(), mentre il metodo element.getBoundingClientRect() restituisce un unico elemento, che è il più piccolo rettangolo che contiene tutti quelli contenuti in element.getClientRects().

 

 

 

Come centrare orizzontalmente e verticalmente un elemento nella pagina web

back to Index

 

 

Per la terminologia che sarà utilizzata (block element e inline element) si veda il paragrafo sugli elementi della pagina web. Sinteticamente si può dire che un block element è un riquadro che può contenere altri riquadri o linee di testo, mentre un inline element è un elemento che è una linea di testo o può essere inserito entro una linea di testo senza produrre un ritorno a capo.

 

Come regola generale, si può porre un block element o un inline element all'interno di un altro block-element e un inline element all'interno di un altro inline element, ma non un block element entro un inline element.

Il primo metodo per centrare orizzontalmente si impiega quando un elemento inline (da centrare) è all'interno di un block-element come <p> o <div>. Si consideri il seguente codice:

 

<div align="center">

Hello World!

</div>

 

o, in alternativa, ricorrendo alle proprietà di stile:

 

<div style="text-align:center">

Hello World!

</div>

 

Esso centrerà orizzontalmente il testo "Hello World!" nella pagina. Ma consideriamo il seguente codice:

 

<div style="text-align:center; width:300px;">

Hello World!

</div>

 

In questo caso il testo non sarà centrato, perché l'elemento <div>, che prima occupava tutta la larghezza della pagina, ora è largo solo 300 pixel e per default viene posizionato a sinistra. Per centrare l'elemento inline (il testo) occorre in questo caso prima centrare il box-element (il tag div), come viene mostrato qui di seguito.

Il secondo metodo per centrare orizzontalmente si può impiegare per posizionare nella pagina un block-element come:

 

<div id="MyDiv" class="MyDivClass">

Questo è il testo da centrare

</div>

 

è sufficiente, nel foglio di stile, settare ad "auto" sia margin-left che margin-right: il browser capirà automaticamente di dover centrare orizzontalmente:

 

<style type ="text/css">

.MyDivClass {

 margin-left: auto;

 margin-right: auto;

}

</style>

 

Se si tratta di un inline element un metodo è quello di agire sull'elemento-genitore (parent element) e settare la proprietà align:

 

<div id="MyDiv" align="center">

<p>Questo è il testo da centrare</p>

</div>

 

Centrare invece l'elemento verticalmente è molto più complicato. In particolare l'istruzione:

vertical-align: middle;

Ma valign agisce solo su celle di tabella, mentre vertical-align agisce solo su celle di tabella e su certi elementi inline. I suoi valori hanno senso rispetto ad un elemento-parent inline.

Ma sfortunatamente vertical-align non si applica a block-level elements, come un paragrafo entro un <div>, che è il caso tipico in cui si ha bisogno di centrare verticalmente.

Il primo metodo per centrare verticalmente si può impiegare quando entro il <div> esiste una sola linea di testo. Si può settare la proprietà css line-height ad un valore superiore a quello reso necessario dal font. Questo spazio aggiuntivo sarà ripartito equamente al disopra e al disotto del testo, che ne risulterà centrato verticalmente. Al limite si può settare l'altezza della linea ad un valore pari a quello dell'elemento <div> che lo contiene, ma questo non è necessario. Ecco un codice tipico:

 

html:

<div id="parent">

  <div id="child">Content here</div>

</div>

css:

#child {line-height: 200px;}

 

Come già detto, questo codice non funziona se ci sono più linee di testo.

Il secondo metodo per centrare verticalmente non è altro che una applicazione del primo metodo agli elementi <img> che contengono una immagine.

html:

div id="parent">

 <img src="image.png" alt="" />

</div>

 

css:

#parent {

  line-height: 200px;

}

 

#parent img {

  vertical-align: middle;

}

 

Il terzo metodo per centrare verticalmente consiste nel settare mediante css il <div> genitore come tabella e l'elemento-figlio come cella di tabella. In tal modo possiamo utilizzare l'istruzione vertical-align: middle ed essa funzionerà.

 

html:

<div id="parent">
  <div id="child">Content here</div>
</div>
 

css:

#parent {display: table}
 
#child {
  display: table-cell;
  vertical-align: middle;
 }
 

 

Il quarto metodo per centrare verticalmente ricorre al posizionamento assoluto dell'elemento-figlio (mentre l'elemento-genitore ha posizionamento relativo). Esso funziona per block-elements all'interno di un altro block-element.

 

html:

<div id="parent">
  <div id="child"></div>
</div>
 

css:

#parent {position: relative}
 
#child {

position: absolute;

    top: 50%;

    left: 50%;

    height: 30%;

    width: 50%;

    margin: -15% 0 0 -25%;

 }

 

Il quinto metodo per centrare verticalmente impiega anch'esso il posizionamento relativo dell'elemento-genitore e il posizionamento assoluto dell'elemento-figlio. In questo caso noterete che i valori del posizionamento assoluto sono "0". Ma quando il browser incontra l'istruzione margin : auto, che si riferisce ai 4 margini, è forzato a distribuirli uniformemente, a destra/sinistra e in alto/basso, centrando l'elemento-figlio.

 

html:

div id="parent">

    <div id="child">Content here</div>

</div>

css:

#parent {position: relative;}
 
#child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 50%;
    height: 30%;
    margin: auto;
}

 

Il sesto metodo per centrare verticalmente consiste nello stabilire i valori del padding (bottom, top, left, right) sia per l'elemento-genitore che per l'elemento-figlio. Questo centrerà il contenuto dell'elemento-figlio e l'elemento-figlio all'interno dell'elemento genitore.

 

html:

 

<div id="parent">
    <div id="child">Content here</div>
</div>
 

css:

#parent {
    padding: 5% 0;
}
 
#child {
    padding: 10% 0;
}

 

I valori di larghezza e altezza dei block-elements sono, nel codice sottostante, non dichiarati. Se si stabilisce un valore per i box occorre fare calcoli più accurati. Per esempio, se l'altezza del genitore è 400 px e del figlio è 100 px noi dobbiamo settare sia padding-top che padding-bottom ad un valore di 150, perché 150 + 150 + 100 = 400.

Invece di operare sul padding si possono settare margini eguali per l'elemento figlio.

Il settimo metodo per centrare verticalmente richiede un <div> vuoto che viene posizionato col metodo del floating, che normalmente viene usato per le immagini.

Con questa proprietà è possibile rimuovere un elemento dal normale flusso del documento e spostarlo su uno dei lati (destro o sinistro) del suo elemento contenitore. Il contenuto che circonda l’elemento scorrerà intorno ad esso sul lato opposto rispetto a quello indicato come valore di float

Ad esempio, con l'istruzione: float : right, l'immagine sarà posizionata nello stesso contenitore allo stesso livello del testo, ma a destra. Più floating elements possono essere disposti uno accanto all'altro con l'istruzione: float : left.

Posizioniamo il floating div a sinistra o a destra e gli diamo un'altezza del 50% del genitore. Il testo viene posto da css al disotto del floating div. Il margin-bottom negativo serve a creare un vuoto sotto il floating element, dove il testo può fluire (altrimenti il testo verrà spinto a destra del floating element).

 

html:

 

<div id="parent">
    <div id="floater"></div>
    <div id="child">Content here</div>
</div>
 

css:

 

#parent {height: 250px;}
 
#floater {
    float: left;
    height: 50%;
    width: 100%;
    margin-bottom: -50px;
}
 
#child {
    clear: both;
    height: 100px;
}

 

Una compagna quasi inseparabile della proprietà float è la proprietà clear che, se applicata ad un elemento successivo ad uno reso float, impedisce che questo subisca il float. L’origine di tale proprietà è questa: visto che il float sposta un elemento dal flusso normale del documento, è possibile che esso venga a trovarsi in posizioni non desiderate, magari al fianco di altri elementi che vogliamo invece tenere separati. clear risolve questo problema. Nell'esempio sopra riportato, l'istruzione clear : both, impedisce che il floating si trasmetta sia da destra che da sinistra.

 

 

 

Come  si crea e si configura una tabella con i fogli di stile

back to Index

 

 

Ecco la struttura essenziale di una tabella con due righe e due colonne:

 

<table>

 <tr>

  <td>

   Questa è la cella della prima colonna, prima riga

  </td>

  <td>

   Questa è la cella della seconda colonna, prima riga

  </td>

 </tr>

 <tr>

  <td>

   Questa è la cella della prima colonna, seconda riga

  </td>

  <td>

   Questa è la cella della seconda colonna, seconda riga

  </td>

 </tr>

</table>

 

I tag <td> rappresentano le celle della tabella, e il testo va inserito al loro interno.

Non si può scrivere direttamente all'interno di un tag <tr>; occorre sempre inserirvi un tag <td> in cui scrivere. In altre parole, non funziona un codice come:

 

<table>

 <tr>

  Questo non funziona

 </tr>

</table>

 

mentre funziona un codice come:

 

<table>

 <tr>

  <td>

   Questo funziona

  </td>

 </tr>

</table>

 

All'interno di un tag <td> può essere inserita un'altra tabella. Attenzione: non si può semplicemente creare un'altra riga e inserire la tabella direttamente nella riga:

...

<tr>

 <table>

  ...

 </table>

</tr>

...

 

Occorre sempre inserire la sotto-tabella in un elemento <td> della tabella principale:

 

<table>

 <tr>

  <td>

   <table>

    ...

   </table>

  </td>

 </tr>

</table>

 

In altre parole, un codice come il seguente, che inserisce la tabella direttamente in una nuova riga, non funziona:

 

<table>

 <tr>

  <table>

   ...

  </table>

 </tr>

</table>

 

A meno che non si voglia configurare diversamente ogni singola cella, per la loro configurazione (margini, ecc.) si impone l'uso di un foglio di stile. Il seguente foglio riquadra ogni cella con un margine in nero (esistono margini separati per la tabella e le celle: settare un margine per la tabella non equivale a settarlo per le celle):

 

css

<style type ="text/css">

 .TableCell

 {

  border : 1px solid black

 }

</style>

 

html

<td class="TableCell"> ... </td>

 

Il valore "1px" indica lo spessore del bordo in pixel.

Il valore "solid" indica che il bordo è una linea continua.

Il valore "black" indica il colore. Per i codici dei principali colori si può consultare la pagina internet http://www.w3schools.com/html/html_colornames.asp.

In alternativa, si dovrebbe introdurre in ciascun tag <td> una dichiarazione di stile del tipo:

 

<td style="border : 1px solid black;">

 

Quando i settaggi del foglio di stile diventano numerosi, questo sistema risulta assai scomodo, perché le stringhe di stile diventano eccessivamente lunghe, ed è preferibile inserire nel tag solo il richiamo ad un foglio di stile.

Chi scrive consiglia, in fase di creazione di una tabella, di inserire sempre margini visibili, perché aiuta notevolmente a capire dove siano situate le celle e gli effetti dei vari comandi di centraggio ecc. (Si tenga presente che è possibile inserire un bordo alle tabelle e alle celle ma non alle righe).

Come si centra orizzontalmente una tabella? E' sufficiente inserire la proprietà align="center":

 

<table align="center">

 

Ecco ora la struttura della tabella arricchita con i fogli di stile:

 

css:

 

<style type ="text/css">

 

 .Table {

  border : 1px solid red;

  padding : 10px;

  border-collapse : separate;

  border-spacing : 10px;

 }

 

 .TableCell {

  border : 1px solid black;

  text-align : center;

  padding : 10px;

 }

 

</style>

 

html:

 

<table class="Table" align="center">

 <tr>

  <td class="TableCell" style="border-color:blue;">

   Questa è la cella della prima colonna, prima riga

  </td>

  <td class="TableCell">

   Questa è la cella della seconda colonna, prima riga

  </td>

 </tr>

 <tr>

  <td class="TableCell">

   Questa è la cella della prima colonna, seconda riga

  </td>

  <td class="TableCell">

   Questa è la cella della seconda colonna, seconda riga

  </td>

 </tr>

 <tr>

  <td class="TableCell" colspan="2">

   <table align="center" style="border:1px solid red;padding:10px;">

    <tr>

     <td class="TableCell">

      Questa è la cella della tabella contenuta nella terza riga

     </td>

    </tr>

   </table>

  </td>

 </tr>

</table>

 

Ed ecco come appare la tabella nella pagina (i bordi delle tabelle sono in rosso, mentre i bordi delle celle sono in nero, tranne quelli della prima, che sono in blu):

 

 

Analizziamo il foglio di stile della tabella più esterna:

 

.Table {

  border : 1px solid red;

  padding : 10px;

  border-collapse : separate;

  border-spacing : 10px;

 }

 

padding : 10px (stabilisce la distanza tra i margini della tabella e i margini delle celle)

border-spacing : 10px (stabilisce la distanza intorno a ciascuna cella) (l'attributo "cellspacing" non è più supportato da HTML5)

border-collapse : separate (stabilisce che i bordi della tabella e delle celle appariranno distinti; va sempre settata come "separate" perché la proprietà "border-spacing" funzioni)

Si noti come la distanza del bordo delle celle dal bordo della tabella più esterna è doppia rispetto alla distanza interna tra i bordi delle celle. Questo perché il valore di "padding" si somma a quello di "border-spacing".

Si noti l'istruzione (evidenziata con lo stesso colore nel codice):

 

<td class="TableCell" colspan="2">

 

Il numero di celle delle righe successive è identico a quello delle righe precedenti, quindi la sotto-tabella verrebbe inserita a sinistra (cella di sinistra della terza riga) e non sarebbe centrabile. Per centrare la sotto-tabella occorre unificare le due righe settando la proprietà "colspan" in modo che la cella si estenda per due colonne.

Analizziamo il foglio di stile delle singole celle:

 

.TableCell {

  border : 1px solid black;

  text-align : center;

  padding : 10px;

 }

 

text-align : center (centra il testo all'interno della cella)

padding : 10px (stabilisce una distanza di 10 pixel tutto intorno al testo, rispetto ai margini della cella: a destra, sinistra, in alto e in basso)

Si noti che sia nel caso della tabella che nel caso della cella, la proprietà "padding" può essere specificata rispetto ad un singolo lato: "padding-left", "padding-right", "padding-top", "padding-bottom".

Anche la proprietà "border-spacing" della tabella può essere settata orizzontalmente e verticalmente inserendo due valori:

 

border-spacing : 10px 20px;

 

Prendiamo in esame ora il modo in cui la tabella esterna è stata centrata orizzontalmente. Questo è stato fatto inserendo " align = 'center' " entro il tag <table>:

 

<table class="Table" align="center">

 

ma questo metodo è ufficialmente sconsigliato (in gergo, "deprecated") a favore dell'uso dei fogli di stile (CSS). La tabella si può centrare orizzontalmente aggiungendo al foglio di stile le istruzioni:

 

margin-left : auto;

margin-right : auto;

 

che fanno capire al browser che lo spazio a destra e a sinistra deve essere identico.

Per operare entro una sola cella una variazione rispetto allo stile assegnato tramite CSS con una dichiarazione di classe è sufficiente inserirvi una dichiarazione di stile del tipo:

 

<td class="TableCell" style="border-color:blue;">

 

con cui abbiamo colorato di blu il bordo della prima cella. La dichiarazione style="…" prevale su quella contenuta nel foglio CSS associato all'elemento tramite la dichiarazione class="TableCell".

Esistono anzi attributi che non possono essere inseriti in un CSS e necessitano di essere inseriti direttamente nel tag. Questo è il caso ad esempio degli attributi:

 

align = "center"

colspan = "2"

 

che non possono essere inseriti in un CSS come

 

align : center;

colspan : 2;

 

Riprendiamo ora in esame l'attributo "colspan" e il suo analogo per le righe: "rowspan". L'attributo "colspan" è utilizzato per raggruppare due celle di colonne adiacenti. Si supponga di avere una tabella composta da due colonne e tre righe. Il suo aspetto normale sarebbe:

 

Applicando l'attributo "colspan", invece, potremmo ottenere una struttura del genere:

 

 

L'attributo "rowspan" è identico al precedente con la differenza che il raggruppamento delle celle non avviene in orizzontale (per colonne) ma in verticale (per righe). Segue un esempio:

 

 

Possono sorgere problemi con l'uso ad esempio di "colspan" quando in un foglio di stile è stato settata la larghezza delle celle ad un valore definito:

 

width : 350px

 

L'effetto che ne risulta è il seguente:

 

 

Come si vede, ora la tabella nella terza riga non occupa l'intera larghezza della riga, come vorremmo, perché, anche se le celle della terza riga sono state ridotte ad una sola cella, questa avrà comunque la stessa larghezza delle altre: 350px, che rappresenta solo metà della larghezza della riga. Per rimediare, si può inserire una variazione di stile nel tag della cella che occupa due colonne, stabilendo una larghezza doppia (700px):

 

<td class="TableCell" colspan="2" style="width:700px;">

 

Una soluzione più elegante sarebbe quella di inserire nei CSS una variazione dello stile "TableCell" limitatamente alle celle con l'attributo " colspan='2' ":

 

.TableCell[colspan="2"] {

  width: 700px;

}

 

Si noti che, in alternativa a nomi di vostra creazione per gli stili di cella, c'è un nome standard ("td") che può essere utilizzato:

 

td {

  border : 1px solid black;

  text-align : center;

  padding : 10px;

 }

 

Ma gli attributi si applicherebbero a tutte le celle di tutte le tabelle della pagina web. In alternativa, come abbiamo fatto noi, si può utilizzare un nome di nostra creazione come ".TableCell" per le celle di ciascuna tabella, oppure utilizzare un selettore, come abbiamo visto fare sopra con "colspan":

 

td[colspan="2"] {

  width: 700px;

}

 

 

 

 

I malfunzionamenti più gravi di Explorer di cui il programmatore javascript dovrebbe essere a conoscenza

back to Index

 

 

Tutte le maggiori applicazioni web, da Yahoo a Google a Facebook ad EBay utilizzano massicciamentte, oltre che il linguaggio html, anche css e javascript, nonché Ajax e PhotoShop.

Microsoft è sempre stata accusata di scarsa attenzione al rispetto degli standard, e lo sviluppo con Internet Explorer 5 e 6 si è rivelato in passato decisamente problematico. Con l'uscita delle versioni 7, 8, 9 le cose sono migliorate, ma ancora oggi siamo lontani da una piena compatibilità e anzi, specifiche CSS ormai molto datate continuano a non essere supportate correttamente nei browser di casa Microsoft.

Quanto ai problemi di compatibilità con le vecchie versioni di Explorer, ormai si può dire che essi sono stati risolti nel senso di un unanime rigetto di tali piattaforme. Ormai tutti gli sviluppatori, dai programmatori indipendenti alle grandi software houses, hanno abbandonato il supporto alle versioni di Internet Explorer (IE) anteriori alla 9, per numerose ragioni: presenza di bachi, problemi di sicurezza, incompleto supporto alle specifiche HTML e javascript, caratteristiche custom non utilizzabili con gli altri browser, e chi più ne ha più ne metta.

Purtroppo, le vecchie versioni di Explorer sono ancora relativamente diffuse; ma siete comunque caldamente sconsigliati dal provare a far funzionare le vostre pagine web con tali versioni. L'unica cosa da fare è far apparire un messaggio che dichiara che il vostro programma non è supportato dalla versione di Explorer presente sul browser, perché anteriore alla 9, e stabilire una istruzione condizionale che disattiva automaticamente il funzionamento delle routine critiche del vostro  sito, mantenendo solo quelle basilari. Ad esempio, il sito dello scrivente blocca l'esecuzione del codice delle ToolTips per timore che possa provocare blocchi o apparizione di fastidiosi messaggi di errore.

L'utilizzo di ajax con Explorer presenta alcuni problemi che illustreremo qui di seguito.

Le versioni precedenti a Explorer 9 non hanno un oggetto XMLHttpRequest nativo incorporato nel modello javascript di documento, quindi è necessario aggiungere all'inizio della propria routine ajax un codice per testare se un tale oggetto esista, e in caso contrario ricorrere al vecchio codice Microsoft ActiveX per crearlo:

 

var XMLHttpRequestObject = false;

if (window.XMLHttpRequest)

{

 XMLHttpRequestObject = new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

 XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

}

 

Il codice Ajax per fare il download dal server di documenti XML non funziona correttamente con Explorer, persino con le versioni più aggiornate. Consideriamo un codice come il seguente:

 

<script language = "javascript">

 XMLHttpRequestObject = new XMLHttpRequest();

 XMLHttpRequestObject.open("GET", "colors.xml");

 XMLHttpRequestObject.onreadystatechange = function()

 {

  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  {

   var xmlDocument=XMLHttpRequestObject.responseXML;

   var colors = xmlDocument.getElementsByTagName("color");

   alert(colors.length);

  }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

 

Questo codice, che funziona perfettamente con Chrome e Firefox, generando un alert box che indica il numero dei tag <color> contenuti nel file colors.xml con Explorer non funziona, per problemi di cache. Internet Explorer è l'unico browser che fa una copia cache automatica di tutti i download effettuati con ajax. Il problema sorge per il fatto che, quando con GET si va a caricare il file colors.xml, Explorer preleva immancabilmente dalla memoria del computer client i dati dell'ultimo download corrispondente alla stessa URL, senza collegarsi al server per acquisire dati aggiornati. Questo provoca immancabilmente malfunzionamenti, e nell'alert compare come numero dei nodi <color> il numero "0", che vuol dire che Explorer considera i dati in formato errato e non li legge.

Per evitare questo inconveniente è sufficiente rendere la URL di ogni chiamata diversa dall'altra aggiungendo ad esempio come parametro una stringa con il tempo del momento in cui viene fatta la chiamata (si veda la riga rossa nel codice di cui sopra):

 

<script language = "javascript">

 XMLHttpRequestObject = new XMLHttpRequest();

   XMLHttpRequestObject.open("GET", "colors.xml?timestamp=" + new Date().getTime());

 XMLHttpRequestObject.onreadystatechange = function()

 {

  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  {

   var xmlDocument=XMLHttpRequestObject.responseXML;

   var colors = xmlDocument.getElementsByTagName("color");

   alert(colors.length);

  }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

 

Persino jQuery non funziona se la cache non è disabilitata. Il codice per disabilitarla è il seguente:

 

$.ajax(

cache: false,

url: 'http://myurl',

data: {}

);

 

 Oppure si può disabilitarla una volta per tutte per le chiamate ajax:

 

$.ajaxSetup({ cache: false });

 

Altri sistemi che si possono provare consistono nella disabilitazione del controllo del tipo di dati che viene fatta da Explorer tramite l'istruzione:

 

<script language = "javascript">

 XMLHttpRequestObject = new XMLHttpRequest();

     XMLHttpRequestObject.overrideMimeType("text/xml");

 XMLHttpRequestObject.open("GET", "colors.xml");

 XMLHttpRequestObject.onreadystatechange = function()

 {

  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  {

   var xmlDocument=XMLHttpRequestObject.responseXML;

   var colors = xmlDocument.getElementsByTagName("color");

   alert(colors.length);

  }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

 

Si può anche indicare ad Explorer che si sta scaricando dati in formato xml:

 

<script language = "javascript">

 XMLHttpRequestObject = new XMLHttpRequest();

     XMLHttpRequestObject.open("GET", "colors.xml");

     XMLHttpRequestObject.setRequestHeader('Content-Type', 'text/xml');

 XMLHttpRequestObject.onreadystatechange = function()

 {

  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  {

   var xmlDocument=XMLHttpRequestObject.responseXML;

   var colors = xmlDocument.getElementsByTagName("color");

   alert(colors.length);

  }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

 

Con Explorer non funziona sempre l'istruzione jQuery:

 

$("#mydiv").load("student.html");

 

e anche in questo caso va disattivata la copia cache automatica (vedi sopra)

 

 

 

Come rilevare le versioni di Explorer e in particolare quelle anteriori a Explorer 9

back to Index

 

 

Ecco un semplice codice consigliato nel sito Microsoft per stabilire se il browser è Explorer ed eventualmente la versione di Explorer:

 

function getInternetExplorerVersion()

// Returns the version of Internet Explorer or a -1

// (indicating the use of another browser).

{

  var rv = -1; // Return value assumes failure.

  if (navigator.appName == 'Microsoft Internet Explorer')

  {

    var ua = navigator.userAgent;

    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");

    if (re.exec(ua) != null)

      rv = parseFloat( RegExp.$1 );

  }

  return rv;

}

 

function checkVersion()

{

  var msg = "You're not using Internet Explorer.";

  var ver = getInternetExplorerVersion();

 

  if ( ver > -1 )

  {

    if ( ver >= 8.0 )

      msg = "You're using a recent copy of Internet Explorer."

    else

      msg = "You should upgrade your copy of Internet Explorer.";

  }

  alert( msg );

}

 

L'unico problema è che questo codice non funziona: infatti, la stringa navigator.appName, anche se il browser è Explorer, è (quasi) invariabilmente "Netscape". Infatti le specifiche del linguaggio HTML5 consentono a qualsiasi browser di dichiarsi "Netscape", ufficialmente per ragioni di compatibilità.

La verità è invece un'altra: sempre più programmatori utilizzavano il codice di rilevazione del tipo e versione del browser per escludere quelli che ritenevano malfunzionanti con il proprio software. I creatori di browser si resero rapidamente conto che se ingenuamente e onestamente dichiaravano il nome e la versione del loro browser nella stringa userAgent, esso rischiava di essere escluso dai programmatori. In particolare Microsoft, il cui browser era all'epoca pieno di caratteristiche customizzate e non supportava pienamente gli standard HTML e javascript era il fornitore che aveva più da temere al riguardo. Ad esempio la stringa userAgent di Explorer 5 è la seguente: "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)". I browser diversi da Explorer, temendo al contrario di essere discriminati, riportavano stringhe userAgent indistinguibili da quelle di Explorer. Il risultato pratico di tutto questo è che le stringhe userAgent sono inservibili e prive di significato.

I programmatori più esperti utilizzano la feature detection, cioè scrivono un codice che controlla specificamente se l'istruzione o la caratteristica che a loro interessa sia supportata dal browser, ma le istruzioni sono lunghe, complesse, numerose, e non sono alla portata del programmatore alle prime armi. Dato che ormai, come già detto, quasi tutti gli sviluppatori hanno deciso di abbandonare il supporto alle versioni di Explorer anteriori alla 9, sarà per la maggior parte delle necessità sufficiente sincerarsi che la versione del proprio browser non sia anteriore alla 9. Ecco un semplice codice per rilevare se la versione del browser che riceve la pagina è precedente a IE 9:

 

function CheckExplorerVersion()

{

 var div = document.createElement("div");

 div.innerHTML = "<!--[if lt IE 9]><i></i><![endif]-->";

 var isIeLessThan9 = (div.getElementsByTagName("i").length == 1);

 if (isIeLessThan9) {return false;}

 else {return true;}

}

 

Ecco una versione più sofisticata, in grado di rilevare tutte le versioni fino alla 9:

 

function CheckExplorerVersion()

{

 var undef;

 var v = 3;

 var div = document.createElement('div');

 while

 (

  div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i>< ! [endif] –>',

  div.getElementsByTagName('i')[0]

 );

 if (v > 4){return v}

 else {return undef}

}

 

La funzione dà i seguenti risultati:

 

CheckExplorerVersion() == undefined (il browser non è Explorer o si tratta di versioni inferiori a Explorer 5 o di Explorer 9 e versioni superiori)

CheckExplorerVersion() == 4 < numero < 9  (Explorer 5, 6 o 7)

 

Entrambi i blocchi di codice si basano su una caratteristica presente nelle versioni di Explorer anteriori alla 9, ma successivamente non più supportata da Microsoft: i commenti condizionali. Un commento condizionale ha la forma seguente:

 

<!--[if expression]> HTML <![endif]-->

 

dove HTML può essere qualsiasi blocco di codice html, comprensivo di tag e di testo. Le principali espressioni standard per testare le versioni di Explorer sono illustrate dai seguenti esempi:

 

[if IE] ("se il browser è Explorer")

[if !IE] ("se il browser non è Explorer")

[if IE 7] ("se il browser è Explorer 7")

[if lt IE 5.5] ("se il browser è una versione di Explorer inferiore a 5.5") ("lt" = "less than")

[if lte IE 6] ("se il browser è una versione di Explorer inferiore o uguale a 6 ") ("lte" = "less than or equal")

[if gt IE 5] ("se il browser è una versione di Explorer superiore a 5 ") ("gt" = "greater than")

[if gte IE 7] ("se il browser è una versione di Explorer superiore o eguale a 5") ("gte" = "greater than or equal")

 

Il codice non fa altro che creare in memoria (senza inserirlo nel documento) un tag <div> che contiene un commento condizionale che crea un elemento <i></i> vuoto (se contenesse qualcosa i caratteri potrebbero essere visualizzati con effetto antiestetico), e poi testare l'esistenza nel tag <div> dell'elemento <i> mediante il codice:

 

div.getElementsByTagName('i')[0]

 

Nelle versioni anteriori alla 5 e successive alla 8 i commenti condizionali non funzionano, e quindi l'espressione ha valore null, che l'istruzione while() trasforma in false.

 

 

 

Cos'è javascript

back to Index

 

 

Javascript è un linguaggio client-side, cioè che viene eseguito dal computer di chi riceve i contenuti web, e che può essere inserito all'interno di una pagina web (normalmente nella sezione head) tra due tag, con istruzioni separate da puntoevirgola, come ad esempio:

 

<script type="text/javascript">

prima istruzione;

seconda istruzione;

..................

ultima istruzione;

</script>

 

oppure entro un tag html, come ad esempio:

 

<p onclick="alert('Hello World');">Clicca qui per far apparire il messaggio</p>

 

Un tag <script> può contenere sia istruzioni separate, che vengono eseguite automaticamente al caricamento della pagina web, che la definizione di funzioni, che vengono invece eseguite quando richiamate:

 

<script type="text/javascript">

 

alert("Hai aperto la pagina web");

 

function MyFunction()

{

 document.write("La funzione è stata richiamata");

}

 

</script>

 

La prima istruzione alert viene eseguita immediatamente: al caricamento appare il messaggio "Hai aperto la pagina web", mentre la funzione MyFunction viene richiamata in seguito e scrive una riga di testo nel documento.

Una funzione ha una struttura tipica:

 

function MyFunction(var1, var2, ...,  varN)

{

 return(var1*var2*...*varN);

}

 

Possono esserle passati dei parametri che sono specificati nella parentesi che la segue o non avere parametri (la parentesi deve comunque essere presente, anche se vuota)

Può restituire un valore con l'istruzione return e/o compiere delle operazioni sul documento o far apparire messaggi.

La struttura tipica di javascript è il richiamo di una funzione al verificarsi di un evento, che consiste principalmente in  un evento di tastiera (onKeyDown, onKeyPress, onScrolling) o in un evento di mouse (onMouseOver, onClick, onMouseOut) o in un evento riguardante l'apertura o la chiusura del documento (onLoad, OnUnLoad). Al verificarsi dell'evento viene richiamata una funzione.

Ecco un elenco degli eventi più comunemente utilizzati:

 

Evento

Si verifica quando…

onabort

una azione è interrotta

onblur

un elemento perde la proprietà focus

onchange

si verifica un cambiamento nel contenuto di un elemento, come ad es. un box di testo

onclick

si è cliccato su un elemento

ondblclick

si è cliccato due volte su un elemento

ondragdrop

è stata eseguita una operazione drag-and-drop (un elemento è stato trascinato nella pagina)

onerror

si è verificato un errore javascript

onfocus

un elemento acquisisce la proprietà focus

onkeydown

un tasto è premuto

onkeyup

un tasto è rilasciato dopo essere stato premuto

onload

viene caricata la pagina

onmousedown

è premuto un bottone del mouse

onmousemove

il mouse è spostato sulla pagina

onmouseout

il mouse esce da un elemento della pagina

onmouseover

il mouse entra nella zona di un elemento della pagina

onmouseup

è rilasciato un bottone del mouse dopo essere stato premuto

onreset

viene cliccato il bottone di reset

onresize

vengono modificate le dimensioni o la posizione di un elemento della pagina

onsubmit

l'utente clicca un pulsante di tipo "submit"

onunload

la pagina è scaricata

onscrolling

si è effettuato lo scrolling della pagina

 

Il codice contenuto nella funzione o in genere in uno script può accedere in lettura e in modifica al contenuto e agli attributi interni (es. l'attributo href e l'attributo title di un tag <a>) di un tag e ai fogli di stile tramite il modello DOM (Document Object Model: vedi più avanti). Può inoltre aprire e leggere files, acquisire data e ora e altri dati riguardanti il sistema, può fare apparire messaggi e ricevere input tramite box di dialogo e di input. Inoltre, javascript implementa un set completo di istruzioni per la lettura di documenti XML.

Ecco di seguito l'esempio di una pagina html in cui cliccando su un elemento si attiva una funzione che dichiara il nome di quell'elemento.

 

<html>

<head>

<script type="text/javascript">

 function MyFunction(MyDiv)

{

 alert("hai cliccato sul " + MyDiv.innerHTML);

}

</script>

</head>

<body>

 

<div onclick="MyFunction(this)">

BOX1

</div>

 

</br>

 

<div onclick="MyFunction(this)">

BOX2

</div>

 

</br>

 

<div onclick="MyFunction(this)">

BOX3

</div>

 

</body>

</html>

 

Alla funzione MyFunction viene inviato come argomento il parametro this, che è un oggetto corrispondente al div in cui è inserita l'istruzione onclick. Questo oggetto consente l'accesso a tutte le proprietà del tag <div>, incluso il testo compreso al suo interno, tramite l'istruzione:

 

MyDiv.innerHTML

 

L'output nella finestra, cliccando su BOX1 è il seguente:

 

 

Aprite la pagina  Experiments_1.htm , per osservare altre cose che possono fare le routines javascript e visualizzatene il codice.

 

 

 

Cos'è jQuery

back to Index

 

 

Javascript è un linguaggio potente e molto migliorato col tempo in termini di performance e di affidabilità, ma il codice risulta piuttosto ingombrante, anche perché col tempo funzionalità non essenziali della pagina, come effetti grafici e animazione, che prima erano affidate a tecnologie differenti come immagini animate o flash, ora sono gestite con javascript. Inoltre, l'accesso alla struttura DOM (Document Object Model) del documento al fine di manipolare gli elementi della pagina avviene attraverso un insieme di API (Application Programming Interface), che sono oggetti e metodi di interfaccia, il cui uso non è affatto banale. La natura fortemente strutturata e gerarchita dei documenti HTML e XML si riflette sulla struttura del DOM, la cui interrogazione e modifica richiede verbose operazioni di iterazione e ricorsione. Il necessario traversamento dell'albero che rappresenta gli oggetti del documento può quindi richiedere una quantità significativa di codice.

Javascript è un linguaggio alquanto laborioso, con un debugging difficile, che non perdona il minimo errore di sintassi (a differenza di HTML) e il minimo scambio di maiuscole e minuscole, e le cui istruzioni sono a volte poco intuitive.

Si aggiunga che ormai è diventato indispensabile al programmatore l'utilizzo di codice Ajax (Asynchronous Javascript and XML): un mix di javascript, xml e php che risulta complicato e poco gestibile se scritto in javascript puro.

Infine, il fatto che esistano più browser e più sistemi operativi rende necessario scrivere altro codice ingombrante (e difficilmente alla portata di un programmatore alle prime armi) per assicurare un minimo di compatibilità della propria pagina con i principali browser.

I programmatori, che in un primo tempo avevano sviluppato soluzioni javascript ciascuno indipendentemente dall'altro, si resero ben presto conto della follia di costruire da soli un sito internet partendo da zero, e sentirono sempre di più la necessità di condividere le routine utilizzate.

Per ovviare a questi inconvenienti sono state rese disponibili in rete, gratuitamente o a pagamento, delle librerie javascript, che racchiudono funzionalità studiate per superare queste limitazioni.

Una delle più affermate è appunto jQuery (http://jquery.com). L'home page del progetto afferma che si tratta di "una libreria JavaScript veloce e concisa che semplifica il traversamento dei documento HTML, la gestione degli eventi, l'animazione e le interazioni Ajax per uno sviluppo web rapido". Al difuori delle parole dei suoi stessi autori, jQuery è comunemente considerato uno dei protagonisti della rinascita della tecnologia javascript soprattutto per via di tre caratteristiche fondamentali: la buona capacità di nascondere le peculiarità dei browser offrendo un'interfaccia e funzionalità omogenee; la possibilità di accedere a elementi della struttura DOM attraverso selettori CSS e la semplicità d'uso. Con jQuery è possibile utilizzare tecnologie all'ultimo grido, come Ajax e CSS, anche su browser che non le supportano direttamente.

Sicuramente, frequentando i blog di argomento tecnico, avrete sentito decantare le potenzialità strepitose di altre librerie javascript, anche in confronto a jQuery. Come scegliere la libreria giusta? Quando si sceglie una libreria per integrare un linguaggio di programmazione, occorre considerarne attentamente il grado di diffusione, perché librerie molto valide ma poco utilizzate finiscono ben presto per non essere supportate dagli sviluppatori e costringono a riscrivere completamente il codice per eliminarle. Da questo punto di vista, jQuery è una libreria affermata sulla Rete da diversi anni e vanta il fatto di essere utilizzata da molte organizzazioni di primaria importanza, come Google, Dell, Bank of America, NBC, CBS, Netflix, Technorati, Mozilla.org, WordPress e Drupal, per citare solo i riferimenti più importanti indicati nell'home page del sito ufficiale della libreria. Infine, jQuery è estremamente leggera (la versione compatta richiede solo 32 Kb, corrispondenti alla quantità di dati di una foto di media qualità).

E' possibile scaricare jQuery dal sito http://jquery.com. L'installazione è molto facile e veloce perché, a differenza di altre complicate librerie, si tratta di un unico file. Viene offerta una scelta di versioni meno recenti e più recenti, tutte perfettamente funzionanti. Ognuna di tali librerie viene resa disponibile in due versioni: quella minifilizzata, da cui sono stati rimossi tutti gli spazi inutili e i ritorni a capo, rendendola praticamente illeggibile ma molto compatta, e quella per lo sviluppo, dotata di ampio commento, che occupa 247 Kb ed è costituita da più di 9400 righe di codice. Sono inoltre disponibili i file migrate, che, scaricati insieme alle librerie più recenti, risolvono tutti i problemi di compatibilità con quelle meno recenti, evitando di dover riscrivere il codice ad ogni aggiornamento.

Nel momento in cui scriviamo la versione più recente è la 1.11.2, (contenuta nel file jquery-1.11.2.min.js) che viene fornita con un file di compatibilità (jquery-migrate-1.2.1.js).

Per poter utilizzare jQuery all'interno della vostra pagina web è sufficiente inserire nell'<head> del documento i seguenti due script:

 

<script src="jquery-1.11.2.min.js"></script>

<script src="jquery-migrate-1.2.1.js"></script>

 

Un modo alternativo e ancora più facile (senza bisogno di scaricare nulla) per includere la libreria jQuery nelle proprie pagine HTML è quello di utilizzare una delle copie gestite dai diversi Content Delivery Network (CDN, network di distribuzione dei contenuti). Un CDN è un sistema distribuito di grande estenzione, costituito da un numero significativo di server ospitati presso più data center sulla Rete. Lo scopo di un CDN è di fornire contenuto agli utenti finali in un contesto di alta affidabilità e in modo performante. I CDN oggi rendono disponibili gran parte dei contenuti della rete, come elementi grafici, script, file multimediali, applicazioni o anche dati in streaming (come musica e video). Su internet esiste un certo numero di CDN commerciali, utilizzati da grandi aziende per la distribuzione di risorse critiche. jQuery è ospitato su diversi CDN, che offrono accesso pubblico e gratuito alla libreria. Ecco tre script alternativi, che fanno riferimento a tre CDN diversi, ciascuno dei quali può essere inserito nel documento risparmiandovi persino la fatica di scaricare il file sul server del vostro sito:

 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

 

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.2.min.js"></script>

 

<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>

 

Convenienza di jQuery rispetto a javascript puro

 

JQuery rende più robuste istruzioni come:

 

var target = document.getElementById("targetDiv");

target.innerHTML = "<p>Hello World</p>";

 

che non funzionano con diverse versioni di explorer, sostituendole con:

 

$("#targetDiv").html("<p>Hello World</p>");

 

che funziona con tutti i browser.

jQuery semplifica istruzioni verbose come:

 

var target = document.getElementById( "targetDiv" );

var newElement = document.createElement( "div" );

target.parentNode.insertBefore( newElement, target.nextSibling );

 

sostituendole con istruzioni più semplici come:

 

$("#targetDiv").after($("<div></div>"));

 

Tanto per fare un esempio del grado di semplicità che si può ottenere con jQuery, ecco qui due blocchi di codice Ajax, uno in javascript puro, l'altro in jQuery, che fanno esattamente la medesima cosa (aprono in modo asincrono il file MyScript.php e mostrano il testo ricevuto entro il documento HTML)

 

codice javascript

 

var XMLHttpRequestObject = false;

if (window.XMLHttpRequest)

{

 XMLHttpRequestObject = new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

 XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

}

function getData()

{

 if(XMLHttpRequestObject)

 {

  var obj = document.getElementById("targetDiv");

  XMLHttpRequestObject.open("GET", "MyScript.php");

  XMLHttpRequestObject.onreadystatechange = function()

  {

   if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

   {

    obj.innerHTML = XMLHttpRequestObject.responseText;

   }

  }

  XMLHttpRequestObject.send(null);

 }

}

 

codice jQuery

 

$.get("MyScript.php",function(Response)

 {

  document.getElementById("targetDiv")= Response;

 },"text");

 

Alcune difficoltà e cautele nell'uso di jQuery

 

Non è assolutamente facile scoprire quale parte del vecchio codice sia incompatibile con le nuove versioni di jQuery, perché, duole dirlo, le indicazioni delle novità e delle incompatibilità sono a dir poco lacunose e difficili da trovare. Lo scrivente si è trovato a dover utilizzare un file di compatibilità accanto a una delle ultime versioni, che altrimenti non funzionava, malgrado abbia tentato con tutti i mezzi di scoprire quali erano le istruzioni da riscrivere:

 

<script src="jquery-1.11.2.min.js"></script>

<script src="jquery-migrate-1.2.1.js"></script>

 

Sebbene venga unanimemente raccomandato di inserire il codice jQuery entro lo spazio di esecuzione condizionale della funzione $(document).ready(), dato da:

 

$(document).ready(function(){...});

 

certe routine non funzionano se poste in tale spazio, mentre funzionano se poste al difuori. Purtroppo, è impossibile sapere a priori quando è necessario mettere del codice entro o fuori tale spazio condizionale.

Prendete ad esempio la seguente pagina internet:

 

<html>

<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<script language = "javascript">

$(document).ready(function(){

alert(document.getElementById("MyIframe").childNodes.length);

});

</script>

</head>

<body>

<iframe id="MyIframe" style="position:absolute;left:30%;top:35%;" src="http://www.w3schools.com"></iframe>

</body>

</html>

 

Sembrerebbe logico porre l'istruzione:

 

alert(document.getElementById("MyIframe").childNodes.length);

 

entro la funzione $(document).ready(), per la ragione, raccomandata dal sito jQuery, che il codice potrebbe altrimenti essere eseguito prima che tutti gli elementi della pagina siano stati caricati, e quindi non potrebbe leggere entro "MyIframe".

Ma in realtà accade esattamente il contrario! Posto entro $(document).ready() l'istruzione non funziona, mentre se posta all'esterno… funziona.

 

 

 

Cos'è il DOM che viene utilizzato da javascript?

back to Index

 

 

Il DOM (Document Object Model) è un modo di rappresentare un documento e i suoi elementi tramite "oggetti" che possiedono attributi e proprietà di lettura/scrittura, metodi e oggetti-figli (parent). il DOM è un’interfaccia, o meglio una API (Application Programming Interface) ideata dal consorzio W3C, che permette di accedere agli elementi di una pagina.

Chi ha già lavorato con Visual Basic for Application Microsoft (VBA) conosce già il tipico codice per esprimere un oggetto. Ecco un tipico oggetto VBA:

 

ActiveDocument.Range.Paragraphs(1)

 

è l'oggetto che si riferisce al primo paragrafo di una selezione in un documento Word. I punti di separazione introducono tipicamente una proprietà, un metodo o un oggetto-parent (figlio).

Ecco un tipico oggetto DOM javascript, che consente di accedere al valore del rientro destro nel corpo del documento:

 

document.body.style.paddingLeft

 

Consideriamo il seguente tag HTML:

 

<a id="MyAnchor" name="MyLink" href="MyFile.htm">Clicca qui per aprire il file</a>

 

Ecco l'oggetto che permette di manipolare il testo "Clicca qui per aprire il file" incluso nel tag:

 

document.getElementById("MyAnchor").innerHTML

 

Ecco l'oggetto che permette di accedere agli attributi "name" e "href" contenuti nel tag:

 

document.getElementById("MyAnchor").attr("name").value

document.getElementById("MyAnchor").attr("href").value

 

Ecco il metodo che consente di scrivere nell'oggetto document

 

document.write("Hello World")

 

 

 

Acquisire e manipolare gli elementi di una pagina tramite javascript e jQuery

back to Index

 

 

 In javascript si chiamano "selettori" le espressioni che permettono di ottenere un singolo elemento o un gruppo omogeneo di elementi del DOM.

Per selezionare tutti i tag <img> con class="class1" oppure class="class2":

$("img.class1, img.class3")

Per selezionare tutti i paragrafi con tag <p> all'interno dell'elemento con id="MyTag":

$(#MyTag p")

$(#MyTag).find(" p")

Per selezionare tutti i tag <input> del documento:

$("input")

Per selezionare tutti i tag con class="MyClass" del documento:

$(".MyClass")

Per selezionare i tag che hanno un certo valore dell'attributo "name" (o qualsiasi altro attributo)

$("[name=MyTagName]")

Per selezionare tutti i tag con la proprietà di stile "hidden":

$(":hidden")

Per selezionare tutti i tag hidden del tag con id="MyTag":

$("#MyTag").find(":hidden")

Il metodo find() svolge una ricerca sui nodi contenuti in quello considerato. Accetta gli stessi argomenti di $(…). Se scriviamo .find("*") otteniamo tutti i discendenti di un elemento.

Consideriamo i seguenti elementi di una pagina HTML:

 

<style type="text/css">

.MyBoxClass{

 width : 200px;

 height : 25px;

 background-color : white;

 font-family : "Times New Roman";

 color : red;

 font-size : 100%;

 vertical-align : center;

 text-align : center;

 border : 1px solid black;

}

</style>

 

<a id="MyAnchor" name="MyLink" href="MyFile.htm">Clicca qui per aprire il file</a>

 

<table>

<tr>

<td id="MyBox" class="MyBoxClass" title="Questo è il mio box">

QUESTO E' IL MIO BOX

</td>

</tr>

</table>

 

<p>

SCRIVI NEL BOX SOTTOSTANTE </br>

<input id="MyTextBox" type="text" >

</p>

 

<div id="MyDiv">

</div>

 

Ecco, di seguito, una serie di modi in cui tali elementi possono essere manipolati.

 

Ottenere (javascript) il testo "Clicca qui per aprire il file" incluso nel tag <a>:

 

document.getElementById("MyAnchor").innerHTML

 

$("#MyAnchor").text()

 

Cambiare (javascript) il testo "Clicca qui per aprire il file" incluso nel tag  <a>:

 

document.getElementById("MyAnchor").innerHTML = "Questo è il nuovo contenuto del tag";

 

Far sparire e riapparire il tag <a>:

 

$('#MyAnchor').hide();

 

$('#MyAnchor').show();

 

$('#MyAnchor').attr("visibility","hidden");

 

$('#MyAnchor').attr("visibility","displayed");

 

L'istruzione "show" funziona anche se il tag <a> è stato dichiarato come invisibile, con l'istruzione di stile:

 

<a style="display:none;">Clicca qui per aprire il file</a>

 

Questo codice ha una interessante applicazione pratica: se si vuole creare un bottone che richiama routine diverse in relazione a due situazioni diverse, invece di scrivere complicate istruzioni condizionali si possono creare due bottoni identici, e far apparire quello che richiama la routine adatta alla circostanza, facendo sparire quello che richiama la routine non adatta alla circostanza.

 

Modificare il colore del testo contenuto nel tag <a>:

 

document.getElementById("MyAnchor").style.color = "red";

 

Leggere (javascript) gli attributi "name" e "href" contenuti nel tag  <a>:

 

document.getElementById("MyAnchor").attr("name").value

document.getElementById("MyAnchor").attr("href").value

 

Leggere (jQuery) gli attributi "name" e "href" contenuti nel tag:

 

$("#MyAnchor").attr("name")

$("#MyAnchor").attr("href")

 

Acquisire i dati presenti nel CSS di MyBox:

 

$("#MyBoxClass").css('height')

 

$(".MyBox").css('height')

 

(il risultato è "25px")

 

Modificare il contenuto del tag <a>  con jQuery:

 

$("#MyAnchor").html("Questa è la nuova stringa inserita nel tag");

 

Cambiare il valore dell'attributo title del box MyBox con jQuery:

 

  $("#MyBox").attr("title", "Questo è sempre il mio box");

 

Leggere il valore dell'attributo title:

 

$("#MyBox").attr('title')

 

Leggere l'eventuale valore di un campo testo dell'oggetto (es. un box di informazioni):

 

$("#MyBox").text()

 

Cambiare l'impostazione di stile contenuta nel foglio CSS abbinato all'elemento con id="MyTag":

 

$("#MyBox").css({width:30});

 

Cancellare tutte le ricorrenze della stringa "px" nel campo che contiene il valore CSS dell'altezza del Box con id="MyTag":

 

$("#MyBox").css('height').replace("px","");

 

Acquisire il contenuto di quanto è stato scritto nel box di testo MyTextBox:

 

document.getElementById("MyTextBox").value

 

$("#MyTextBox").val()

 

$("MyTextBox").attr("value")

 

Acquisire la lunghezza della stringa che è stata immessa in MyTextBox (ad es. per controllare se sia stato correttamente digitato il numero di una carta di credito):

 

$('#MyInputBox').attr('value').length

 

Immettere del testo nel box MyTextBox

 

$('#MyTextBox').val("Hello World");

 

Non solo è possibile, sia con javascript che con jQuery, immettere nella pagina una semplice stringa di testo, ma anche altri tag, come paragrafi, e persino tabelle, dotati delle caratteristiche di stile desiderate.

Ecco ad esempio, come far comparire in MyDiv un paragrafo con una riga di testo:

 

$('#MyDiv').html("<p style='font-size:150%;color:blue;font-weight:bold;'>" +'ABRACADABRA'+"</p>");

 

oppure:

 

document.getElementById("MyDiv").innerHTML = "<p style='font-size:150%;color:blue;font-weight:bold;'>" +'ABRACADABRA'+"</p>");

 

to be continued…

 

 

 

Come si costruisce un oggetto javascript

back to Index

 

 

Un oggetto è una entità javascript che può essere dotata di proprietà e metodi definiti dal programmatore, mediante la dot notation. Ad es. possiamo avere la proprietà MioGatto.nome, o MioGatto.razza, il metodo MioGatto.apprezza().

Un primo modo di creare oggetti javascript è di utilizzare il costruttore predefinito Object(), che crea oggetti vuoti, ovvero privi di proprietà e metodi. Le proprietà degli oggetti costruiti con Object() devono essere definite successivamente alla creazione.

Creiamo ad esempio un nuovo oggetto di nome mioCell, con 4 proprietà:

 

var mioCell = new Object;

mioCell.marca = "LG";

mioCell.colore = "bianco";

mioCell.display = 16000colori";

mioCell.mms = "si";

mioCell.camera = "si";

 

Un secondo modo di creare oggetti è tramite un costruttore personalizzato:

 

function Automobile(marca, modello, colore, cilindrata)

{

 this.marca=marca;

 this.modello=modello;

 this.colore=colore;

 this.cilindrata = cilindrata;

 this.trazione;

 this.carburante = 5;

}

 

Si notino le proprietà "trazione" e "carburante": il valore di "trazione" verrà assegnato in seguito, all'istanza dell'oggetto:

 

var punto = new Automobile;

punto.trazione = "integrale";

 

Alla proprietà "carburante" è assegnato sin dall'inizio un valore di default che può essere cambiato una volta creata una istanza dell'oggetto.

 che può essere scritta/letta ma non necessita di inizializzazione al momento della creazione dell'oggetto. Si noti la proprietà "carburante", che viene inizializzata dal codice dell'oggetto.

Disponendo del costruttore, si può creare una istanza del tipo di oggetto definito, che è quanto stiamo cercando:

 

var punto = new Automobile("Fiat", "Punto", "rosso", "1200");

 

Queste proprietà possono essere modificate in modo molto semplice:

 

punto.colore = "argento";

 

utilizzando la dot notation.

Una volta che si è istanziato un nuovo oggetto Automobile, si possono aggiungere altre proprietà, che non sono proprie della classe, ma solo di quell'oggetto:

 

punto.alimentazione = "gasolio";

 

Per costruire un metodo si ricorre alla definizione di una funzione. Sviluppando l'esempio della classe "Automobile", definiamo :

 

function Automobile(marca, modello, colore, cilindrata)

{

 this.marca = marca;

 this.modello = modello;

 this.colore = colore;

 this.cilindrata = cilindrata;

 this.trazione;

 this.carburante = 5;

 this.rifornimento = function(litri)

 {

  if(this.carburante + litri * 1 >=50)

  {

   this.carburante=50;

  }

  else

  {

   this.carburante = this.carburante + (litri*1);

  }

  operazione.value = this.carburante + " Litri";

 }

 this.pieno = function()

 {

  this.carburante = 50;

  operazione.value = 50 + " Litri";

 }

 this.viaggia = function(km)

 {

  if (this.carburante - (km/10) >=0)

  {

   this.carburante = this.carburante - km/10;

  }

  else

  {

   this. carburante = 0;

  }

  operazione.value = this.carburante + "Litri";

 }

}

 

Per vedere come funzionano i metodi, creiamo un nuovo oggetto "punto" corrispondente alla classe "Automobile":

var punto = new Automobile("Fiat", "Punto", "rosso", 1200);

 

Inoltre, inseriamo una textbox in cui inserire il livello del serbatoio:

 

Litri serbatoio: <input type="text" id="operazione" size="3" value="5 Litri">

 

Il metodo Automobile.rifornimento (evidenziato in rosso) viene richiamato dal bottone:

 

<input type="button" value="Rifornisci" onclick="punto.rifornimento(prompt('litri?',''))">

 

che fa apparire un prompt che chiede quanti litri di rifornimento sono stati aggiunti al serbatoio, vi aggiunge la quantità di carburante già presente nel serbatoio (che compare nel box di testo), e fa apparire nel box di testo i litri totali immessi.

Il metodo Automobile.pieno (evidenziato in viola) viene richiamato dal bottone:

 

<input type="button" value="Rifornisci" onclick="punto.rifornimento(prompt('litri?',''))">

 

che fa apparire un prompt che chiede quanti litri di rifornimento sono stati aggiunti al serbatoio, vi aggiunge la quantità di carburante già presente nel serbatoio (che compare nel box di testo), e fa apparire nel box di testo i litri totali immessi.

 

<input type="button" value="Fai il pieno" onclick="punto.pieno()">

 

e si limita a visualizzare "50 Litri" nel box di testo.

Il metodo Automobile.viaggia (evidenziato in verde) viene richiamato dal bottone:

 

<input type="button" value="Viaggia" onclick="punto.viaggia(prompt('Km percorsi',''))">

 

fa apparire un prompt che richiede il numero di kilometri percorsi e sottrae ai litri del serbatoio (nel box di testo) quelli consumati in relazione ai kilometri percorsi.

Un oggetto può essere definito e instanziato contestualmente tramite un codice come il seguente:

 

trapezio =

{

 BaseMinore : 10;

 BaseMaggiore : 20;

 Altezza : 15;

 area : function()

 {

  return (this.BaseMinore + this.BaseMaggiore) * this.Altezza / 2;

 }

}

 

La proprietà "prototype" di un oggetto è un modo per riferirsi globalmente alle proprietà e ai metodi di quell'oggetto. Per capire a cosa serva la proprietà "prototype", creiamo due oggetti (costruttori). Creiamo dapprima l'oggetto "EssereVivente":

 

EssereVivente = function()

{

 this.nome="";

 this.cosaMangia="";

 this.setCosaMangia = function(cibo)

 {

  this.cosaMangia=cibo;

 }

}

 

Creiamo poi l'oggetto "Mammifero":

 

Mammifero = function()

{

 this.razza="";

 this.dataNascita="";

}

 

Come fare per far ereditare tutte le proprietà e i metodi di "EssereVivente" a "Mammifero"? Semplice: facendo riferimento al "prototype" di "Mammifero" e inserendovi le proprietà e i metodi di "EssereVivente":

 

Mammifero.prototype = new EssereVivente;

 

In tal modo ogni istanza dell'oggetto "Mammifero" erediterà anche le proprietà di "EssereVivente".

Se si vuole inserire una singola proprietà o metodo ad un oggetto si deve prima crearla:

 

function DisplayRazza()

{

 alert("La razza di questo animale è: " + this.razza);

}

 

Successivamente si inserisce il metodo DisplayRazza nell'oggetto "Mammifero":

 

Mammifero.prototype.DisplayRazza = DisplayRazza;

 

In questo modo tutte le istanze dell'oggetto mammifero create successivamente alla inclusione di questo metodo, avranno la possibilità di utilizzarlo, ma non quelle create anteriormente.

 

 

 

Racchiudere un contenuto troppo grande per lo spazio assegnato nella pagina entro un box con barre di scorrimento verticali e orizzontali

back to Index

 

 

Osservate questa pagina web:

 

 

essa corrisponde al seguente codice:

 

<html>

<head>

<style>

#myDIV {

 border:1px solid black;

 height: 250px;

 width: 250px;

 overflow: auto;

 position:absolute;

 top:20%;

 left:35%;

}

 

#content {

 height: 800px;

 width: 2000px;

 background-color: HoneyDew;

}

</style>

</head>

<body>

 

<div id="myDIV">

  <div id="content">

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

   Il contenuto dell'elemento interno eccede quello dell'elemento esterno</br>

  </div>

</div>

 

</body>

</html>

 

La riga di codice responsabile dell'effetto scrolling è evidenziata in colore rosso scuro (vedi):

 

overflow: auto;

 

La proprietà overflow può avere diversi valori, i più utili dei quali sono:

 

overflow: visible|hidden|scroll|auto;

 

overflow : visible avrebbe fatto "fuoriuscire" il contenuto dell'elemento interno dai limiti dell'elemento esterno, invadendo la pagina. Questo è il valore di default. Per impedire questo, normalmente si setta il margine dell'elemento esterno come auto, in modo che si adatti all'elemento interno.

overflow : hidden taglia semplicemente il contenuto eccedente le dimensioni dell'elemento esterno, rendendolo invisibile e irraggiungibile (non c'è scrolling)

overflow : scroll taglia il contenuto eccedente le dimensioni dell'elemento esterno, ma lo rende accessibile dotando quest'ultimo di barre per lo scrolling verticale e orizzontale.

overflow : auto se il contenuto eccede le dimensioni dell'elemento esterno, fa apparire delle barre per lo scrolling. Rispetto all'opzione overflow : scroll, è più conveniente, perché, mentre in quel caso le barre appaiono sempre, anche se il contenuto è compreso nei limiti dell'elemento, con overflow : auto esse compaiono solo se il contenuto eccede le dimensioni assegnate.

 

 

 

La proprietà documentElement

back to Index

 

 

Quando si dispone di un documento strutturato mediante tag, come una pagina web:

 

<html>

<head> … </head>

<body> … </body>

</html>

 

oppure come un documento xml:

 

<catalogo>

 

<scheda>

<autore> … </autore>

<titolo> … </titolo>

<editore> … </editore>

<scheda>

 

<scheda>

<autore> … </autore>

<titolo> … </titolo>

<editore> … </editore>

<scheda>

 

</catalogo>

 

E' possibile leggerne il contenuto tramite apposite istruzioni, che fanno riferimento ai nodi del documento. Un nodo è un tag o il contenuto (testo o immagine) di un tag. Per poter fare questo occorre acquisirlo come documento strutturato con una istruzione del tipo:

 

var mydocument = document.documentElement

 

(caso di un file con il codice di una pagina web)

oppure con una istruzione del tipo:

 

xmlDoc=loadXMLDoc("books.xml");
mydocument=xmlDoc.documentElement;

 

(caso di un file xml)

Proviamo ad esempio ad acquisire la seguente pagina html come documento strutturato in nodi:

 

<html>

<head>

</head>

<body>

 

<div id="MyDiv">

 Questo è il testo contenuto nel tag div

</div>

 

<table id="MyTable">

<tr>

<td>

 Questo è il testo contenuto nel tag td

</td>

</tr>

</table>

 

</body>

</html>

 

Con la proprietà .documentElement si acquisisce il nodo principale, che racchiude gli altri nodi. Ecco il codice per leggere il testo contenuto nel tag <div> e farlo apparire entro un alert box:

 

alert(document.documentElement.getElementsByTagName("div")[0].firstChild.nodeValue);

 

Ecco il codice per leggere il testo contenuto nel tag <td> della tabella e farlo apparire entro un alert box:

 

alert(document.documentElement.getElementsByTagName("div")[0].firstChild.nodeValue);

 

L'output che otteniamo in questo secondo caso nella pagina web è:

 

 

Con apposite istruzioni possiamo navigare attraverso i nodi per acquisirne il valore. Ecco ad esempio il codice per acquisire il nome del tag <head> del documento html e farlo apparire in un alert box:

 

alert(document.documentElement.firstChild.nodeName);

 

L'output che otteniamo è il seguente:

 

Riguardo il nodo si possono ottenere tra le altre le proprietà .nodeName, nodeValue e nodeType, su cui ci soffermeremo in seguito

 

 

 

Subordinare l'apertura di un link al valore vero/falso di una funzione javascript

back to Index

 

 

Osservate il codice seguente:

 

<html>

<head>

<script text="javascript">

 function Controllo(){

  return true;

 }

</script>

</head>

<body>

<a href="MyFile.htm" onclick="return Controllo();">Clicca qui per aprire il file</a>

</body>

</html>

 

Il file MyFile.htm, a cui fa riferimento il link <a>…</a> si aprirà solo se la funzione "Controllo()" restituisce "true"  (come in questo caso), mentre se restituisce "false" il link rimarrà inattivo.

 

 

 

Tracciare la posizione relativa e assoluta del mouse entro la finestra, indipendentemente dallo scrolling

back to Index

 

 

Aprite il documento MouseTracking.htm e visualizzate il codice con l'opzione "visualizza sorgente pagina" del tasto destro del mouse (per Explorer l'opzione è "HTML").

Al passare del mouse su uno dei box una funzione jQuery visualizza le informazioni di posizione del mouse:

 

  $('.MyBox').mousemove

  (

   function(event)

   {

    log2("Window Height : "+window.innerHeight+

     "</br>Top Box : "+Math.floor($(this).offset().top)+

     "</br>Left Box : "+Math.floor($(this).offset().left)+

     "</br>Box Height : "+$(this).css('top')+

     "</br>Box Width : "+$(this).css('top')+

     "</br>Window Width : "+window.innerWidth+

     "</br>Absolute Mouse X : "+event.pageX+

     "</br>Absolute Mouse Y : "+event.pageY+

     "</br>Window Mouse X : "+event.pageX+

     "</br>Window Mouse Y : "+(event.pageY-document.VerticalScrollValue));

   }

  );

 

Window Width è la larghezza utile (innerWidth) della finestra in punti

Window Height è l'altezza utile (innerHeight) della finestra in punti

(provate ad aumentare l'ingrandimento della finestra con CTRL+rotella del mouse e noterete che Window Width si riduce quando l'ingrandimento aumenta, e così pure capita a Window Height)

Top Box è la distanza in punti del margine superiore del box dall'inizio del documento (non della finestra)

Left Box è la distanza in punti del margine sinistro del box dal lato sinistro del documento (non della finestra)

Box Height è l'altezza del box in punti, letta nel foglio CSS

Box Width è la larghezza del box in punti, letta nel foglio CSS

Absolute Mouse X è la distanza in punti del mouse rispetto al lato sinistro del documento (non della finestra)

Absolute Mouse Y è la distanza in punti del mouse rispetto al lato superiore del documento (non della finestra)

Window Mouse X è la distanza in punti del mouse rispetto al lato sinistro della finestra, cioè tenendo conto dello scrolling

Window Mouse Y è la distanza in punti del mouse rispetto al lato superiore della finestra, cioè tenendo conto dello scrolling

 

Un'altra funzione jQuery fa apparire invece, in un'altra finestra, i dati dello scrolling verticale e orizzintale in punti, che sono indispensabili per ottenere la posizione del mouse relativa alla finestra, e non al documento:

 

$(window).scroll(function(event)

 {

  log1("Scrolling verticale: "+$(window).scrollTop()+"</br>Scrolling orizzontale : "+$(window).scrollLeft());

  document.VerticalScrollValue=$(window).scrollTop();

  document.HorizontalScrollValue=$(window).scrollLeft();

 });

 

Chi ha esperienza di javascript non mancherà di notare la maggiore facilità di acquisizione dei dati con jQuery, che permette persino di accedere alle misure di larghezza e altezza del box.

 

 

 

Acquisire la posizione di un elemento entro il documento

back to Index

 

 

Consideriamo la seguente rappresentazione di un box come visualizzato in una pagina web:

 

box_container.png (291×281)

 

Questo box corrisponde al seguente codice:

html:

<div id="container">

</div>

 

css:

#container {

padding: 24px;

margin: 24px;

border: 50px #ccc solid;

left: 10px;

top: 200px;

position: absolute;

}

 

I valori padding, margin, border, left, top influiscono tutti sulla posizione che il contenuto del box ha nella pagina: ad esempio, aumentando il padding o il margine, una eventuale linea di testo scenderà più in basso nella pagina.

Un elemento immagine invece avrà una struttura più semplice:

 

http://www.kirupa.com/html5/images/box_container_boring.png

 

La nostra immagine è situata nel suo contenitore e non ha valori definiti per padding, margin o border.

Consideriamo ora una pagina web che mostra elementi annidati:

 

I bordi rossi sono quelli di una tabella, mentre i bordi neri sono quelli di una cella della tabella. Abbiamo tre tabelle annidate che contengono altrettante celle.

Questa visualizzazione corrisponde al codice seguente:

 

<table align="center" style="border:1px solid red;width:auto;height:auto;padding:20px;">

 <tr>

  <td style="border:1px solid black;width:300px;height:200px;padding:20px;">

   <table align="center" style="border:1px solid red;width:auto;height:auto;padding:20px;">

    <tr>

     <td style="border:1px solid black;width:300px;height:200px;padding:20px;">

      <table align="center" style="border:1px solid red;width:auto;height:auto;padding:20px;">

       <tr>

        <td id="MyBox" style="border:1px solid black;width:300px;height:200px;text-align:center;font-size:120%;font-weight:bold;">

         MyBox

        </td> 

       </tr>

      </table>

     </td> 

    </tr>

   </table>

  </td>

 </tr>

</table>

 

Come si può acquisire la posizione della cella MyBox all'interno del documento? Ecco un codice che lavora risalendo dall'elemento interno a quelli più esterni, sommando via via le posizioni all'interno dell'oggetto contenitore (parent):

 

function getPosition(element)

{

var xPosition = 0;

var yPosition = 0;

while(element)

 {

  xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);

  yPosition += (element.offsetTop - element.scrollTop + element.clientTop);

  element = element.offsetParent;

}

return { x: xPosition, y: yPosition };

}

 

L'argomento della funzione è un elemento della pagina; nel nostro esempio essa è richiamata dall'istruzione:

 

function getPosition(document.getElementById("MyBox"));

 

Il loop while inizia con l'elemento designato, ed aggiunge a xPosition e yPosition i valori che andiamo a commentare:

Le proprietà offsetLeft e offsetTop restituiscono la posizione a sinistra e dall'alto relativa all'elemento-genitore più prossimo, cioè la distanza dell'angolo superiore sinistro dell'elemento considerato rispetto all'angolo superiore sinistro dell'elemento-genitore. Normalmente è il valore di padding che fa sì che questi due angoli non coincidano, facendo rientrare l'elemento-figlio.

Le proprietà clientLeft e clientTop tengono conto dello spessore rispettivamente del bordo sinistro e del bordo superiore dell'elemento (che sono quelli rilevanti per il posizionamento)

Le proprietà scrollLeft e scrollTop riguardano il contenuto di ogni elemento, e misurano lo scrolling interno di tale contenuto. Questa è la ragione per cui i relativi valori vengono sottratti, piuttosto che addizionati.

 

Un altro modo, più veloce, di ottenere lo stesso risultato, è quello di utilizzare il metodo getBoundingClientRect(), che è supportato attualmente da tutti i browser.

Il metodo viene applicato ad un elemento, ad esempio con l'istruzione:

 

document.getElementById("MyBox").getBoundingClientRect()

 

Per capire l'oggetto che si ottiene, occorre premettere che, secondo le specifiche CSS, qualsiasi contenuto della pagina web è racchiuso in un rettangolo chiamato "CSS box". Nel caso di un block-element come <div> è l'elemento stesso che forma un simile rettangolo, chiamato block box. Nel caso di un inline element, ogni ritorno a capo genera un box: ogni linea è un rettangolo e questi rettangolo sono chiamati anonymous boxes. In tal modo il contenuto di un elemento può consistere di un unico rettangolo o di rettangoli multipli, che è possibile richiamare con il metodo element.getClientRects(). Il metodo element.getBoundingClientRect() restituisce il minimo rettangolo che racchiude tutti i rettangoli che sono in element.getClientRects().

La funzione che consente di ottenere la posizione dell'elemento per questa via si presenta nel modo seguente:

 

function getOffsetRect(elem)

{

 // (1)

 var box = elem.getBoundingClientRect();

 var body = document.body;

 var docElem = document.documentElement;

 // (2)

 var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;

 var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

 // (3)

 var clientTop = docElem.clientTop || body.clientTop || 0;

 var clientLeft = docElem.clientLeft || body.clientLeft || 0;

 // (4)

 var top  = box.top +  scrollTop - clientTop;

 var left = box.left + scrollLeft - clientLeft;

 return { top: Math.round(top), left: Math.round(left) };

}

 

Si notino le istruzioni condizionali come:

 

var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;

 

Il significato delle due sbarre verticali "||" è simile a quello logico "or", in quanto acquisisce il primo elemento non nullo dell'insieme. Così, una istruzione come:

 

alert("" || "paperino" || "pluto");

 

restituirà "paperino", mentre l'istruzione:

 

alert("pippo" || "paperino" || "pluto");

 

restituirà "pippo".

Consideriamo ora il documento web prodotto dal seguente codice:

 

<html>

<head>

</head>

<body>

 

<p id="MyParagraph" align="center" style="border:1px solid black;">

Questo è il mio paragrafo

</p>

 

</body>

</html>

 

Con la proprietà offset() di jQuery possiamo ottenere la posizione del box che racchiude l'elemento relativa al documento:

 

$("#MyParagraph").offset().top

 

Si può vedere come la proprietà offset() ha due valori: offset().top e offset().left, che determinano la posizione del box.

Questa istruzione fornisce il valore "8", e non "0", come ci si sarebbe aspettato per il primo elemento della pagina, perché il browser normalmente pone una piccola distanza tra l'elemento e il margine superiore della finestra.

Il metodo offset() può essere utilizzato sia in lettura che scrittura, cioè per settare le coordinate. Ad esempio l'istruzione:

 

$("#MyParagraph").offset({top: 200,left:200});

 

sposta l'elemento alle coordinate 200, 200.

Gli stessi risultati si possono ottenere con position():

 

$("#MyParagraph").position().top

 

La differenza tra i metodi position() offset() di jQuery sta nel modo con cui vengono calcolate le coordinate restituite. Nel primo caso, le coordinate vengono calcolate sempre rispetto al genitore dell’elemento, mentre nel secondo caso tali coordinate possono essere calcolate rispetto all’offset dell’elemento genitore rispetto alla pagina quando il genitore è posizionato, ossia ha un valore CSS diverso da static. Se il genitore non è posizionato, entrambi i metodi restituiscono gli stessi valori. 

Un'altra utile proprietà è offsetParent. Consideriamo il seguente elemento:

 

<div id="MyDiv" style="position:absolute;top:200px;left:100px;">

 <p id="MyParagraph" class="paragraph" align="center">

 Questo è il mio paragrafo

 </p>

</div>

 

Consideriamo la seguente istruzione:

 

alert($(document.getElementById("MyParagraph").offsetParent).offset().top);

 

Il valore che sarà mostrato nel box di dialogo è 200, perché l'elemento parent di MyParagraph è il <div> che lo contiene, e che ha un posizionamento assoluto dato dai valori:

 

top : 200px

left : 100px.

 

Un'altra proprietà utile per calcolare la posizione di un elemento è .clientTop, che indica lo spessore del bordo superiore dell'elemento, in pixel (per il bordo sinistro si utilizza .clientLeft). Considerando l'elemento:

 

<div id="MyDiv" style="border:10px">

 <p id="MyParagraph" class="paragraph" align="center">

 Questo è il mio paragrafo

 </p>

</div>

 

l'istruzione:

 

alert(document.getElementById("MyParagraph").offsetParent.clientTop);

 

dà come valore "10", che corrisponde al valore dato alla proprietà border-top di MyDiv. Come si vede questa istruzione non appartiene a jQuery, ma a javascript, quindi non funziona se associata ad un identificatore jQuery:

 

alert($("#MyParagraph").offsetParent.clientTop);

 

Tuttavia clientTop non tiene conto degli effetti della proprietà padding, né della proprietà margin. Al suo posto si può usare la proprietà .style.borderTopWidth.

 

 

 

Fare lo scrolling fino a portare un elemento della pagina in vista

back to Index

 

 

Consideriamo la seguente pagina web Scrolling.htm :

 

<html>

<head>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>

 

<script type="text/javascript">

 

$(document).ready(function(){

 $("#MyButton").offset({top: 200, left: 600});

 $("html,body").scrollTop(0);

});

 

function MyFunction()

{

 var offset = $("#MyButton").offset();

 offset.top = offset.top - 50;

 $("html,body").scrollTop(offset.top);

}

 

</script>

</head>

<body>

<div style="height:1000px;"></div>

<p align=center>

<input id = "MyButton" type="button" value="INVIO" onclick="MyFunction();">

</p>

<div style="height:1000px;"></div>

</body>

</html>

 

Le istruzioni javascript utilizzano la proprietà .scrollTop() associata ad un qualsiasi elemento, che permette di leggerne o settarne lo scrolling interno. Quest'ultimo rilievo vuol dire che non riusciremo a muovere in alto di 50 pixels il bottone con l'istruzione:

 

$("#MyButton").scrollTop(50);

 

bensì con l'istruzione:

 

$("html,body").scrollTop(50);

 

perché lo scrolling si riferisce ad un eventuale contenuto dell'elemento, e quindi l'elemento a cui dobbiamo associare l'istruzione non è il tag del bottone ma il tag <body>, all'interno del quale si trova il bottone.

Nel documento appare un bottone:

 

<input id = "MyButton" type="button" value="INVIO" onclick="MyFunction();">

 

che viene posizionato 200 punti in basso a partire dall'inizio del documento e 600 punti a destra a partire dal lato sinistro del documento:

 

$("#MyButton").offset({top: 200, left: 600});

 

L'evento onclick del tag MyButton richiama una funzione:

 

onclick = "MyFunction();"

 

La funzione MyFunction acquisisce la posizione verticale del bottone mediante :

 

var offset = $("#MyButton").offset();

 

Se noi facessimo lo scrolling in basso pari a tale valore (cioè 200 punti), il bottone salirebbe fino a sparire dalla vista.

Poiché vogliamo che dopo lo scrolling il bottone sia posizionato 50 punti più in basso dell'inizio della finestra, occorre fare lo scrolling di un valore pari alla posizione dell'elemento meno 50 punti:

 

offset.top = offset.top - 50;

 

Ora, facendo lo scrolling del documento, il bottone verrà posizionato esattamente 50 punti in basso a partire dall'inizio della finestra.

 

 

 

Dotare una pagina web di ToolTip (box informativi che appaiono quando il mouse passa sopra ad un elemento)

back to Index

 

 

Cos'è una "tooltip"? E' un box informativo che compare quando il mouse passa sopra un elemento della pagina, che potrebbe essere un link, un tag <td> di una tabella o un altro tag (jQuery permette di dotare di tooltip un tag qualsiasi).

La soluzione che proponiamo qui è dovuto ad Alessio Atzeni, e si può trovare sul suo sito www.alessioatzeni.com.

 

attenzione: Se dopo aver dotato la vostra pagina di tooltips voleste automatizzare le operazioni di inserzione delle informazioni nel campo "title", scrivendole in un documento XML e inserendole nel tag al momento del caricamento della pagina, consultate in questo documento l'articolo "Inserire nel campo 'title' dei vostri link le informazioni visualizzate dal browser al passaggio del mouse utilizzando XML, javascript e php"

 

Per creare le tooltips vengono utilizzati i seguenti linguaggi o funzionalità: html, css, javascript, jQuery.

Noi abbiamo apportato diversi miglioramenti al codice, di cui diamo un sintetico elenco (ciascuno sarà spiegato in dettaglio più avanti):

 

  Alcune istruzioni sono state sostituite da altre più comprensibili per i principianti e il codice è stato lievemente modificato e indentato in modo da renderlo più leggibile.

  E' stata aggiunta una condizione che fa apparire la ToolTip solo per i box con campo "title" non vuoto (il codice di Atzeni faceva comparire un antiestetico box vuoto)

  Il codice funziona con elementi appartenenti a classi diverse, non solo con con elementi di una sola classe.

  L'inserzione del testo nei tooltip è stata razionalizzata tramite caricamento da un file xml (questa funzionalità non sarà implementata in questo articolo, ma sarà oggetto di una trattazione indipendente)

  La ToolTip si autoconfigura in relazione al contenuto, in modo da avere una larghezza doppia dell'altezza

  Il testo della ToolTip è stato formattato in modo più elegante, con giustificazione dei margini

  La posizione della ToolTip si modifica rispetto a quella di default (in basso e a destra rispetto al box) ogni volta che, data la posizione del box, rischia di uscire dallo schermo.

 

Per vedere il codice javascript, aprite il file PaginaConTooltip.htm dal sito learningsources e fate visualizzare al browser il sorgente nel seguente modo:

Con Chrome, tasto destro del mouse, opzione "visualizza sorgente pagina"

Con Mozilla, tasto destro del mouse, opzione "visualizza sorgente pagina"

Con Explorer, tasto destro del mouse, opzione "HTML"

 

Esponiamo in breve la struttura del codice che consente di creare tooltips. Il file PaginaConTooltip.htm visualizza dei box costituiti da celle di tabella generate dal seguente codice:

 

<td class="MyBox" title="Questo è un box di informazioni">  </td>

 

Come si vede ogni tag <td> ha al suo interno l'attributo "title", in cui viene inserito il testo da visualizzare nella tooltip. Quando il mouse passa sul box, si attiva una routine jQuery collegata all'evento mouseover, che genera e fa apparire la tooltip InfoBox, che non è altro che un semplice paragrafo di testo formattato con il foglio di stile .tooltip, che ne definisce il bordo, il colore di background, la giustificazione e il font del testo, setta il posizionamento come assoluto (position : absolute) e la non-visibilità (display : none):

 

InfoBox =$("<p class='tooltip'></p>");

 

Subito dopo viene posto all'interno della tooltip InfoBox il testo che è contenuto nell'attributo "title" del box:

 

InfoBox.text(title)

 

La tooltip InfoBox viene poi inserita nel documento con l'istruzione .appendTo() e fatta apparire con fadeIn(), e posizionata in modo assoluto a sinistra e in basso rispetto alla posizione corrente del mouse, tramite il seguente codice:

 

$('.tooltip').offset({top: mousey,left: mousex});

 

dove mousex e mousey definiscono lo scostamento orizzontale e lo scostamento verticale del margine superiore sinistro di InfoBox rispetto alla posizione del mouse.

 

Dopo questi brevi cenni introduttivi, passiamo ad analizzare nel dettaglio il codice di PaginaConTooltip.

Si noti anzitutto, nella sezione <head>, il richiamo alle libreria jQuery, indispensabile per scrivere un codice compatto ed efficiente:

 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

 

In questo caso, per evitare di dover scaricare sul proprio computer il file jquery-1.11.2.min.js, si è utilizzato un CDN (Content Delivery Network), cioè si è fatto riferimento, nel link, a una copia della libreria ospitata su server che la mettono a disposizione gratuitamente degli utenti di internet (in questo caso si tratta dei server Google):

 

Diamo un'occhiata al codice che genera i box: si tratta di tre fogli CSS posti nella sezione <head> e di una tabella posta nella sezione <body>.

I fogli CSS definiscono tre classi: una per i box veri e propri (classe .MyBox), una per gli interstizi verticali tra i box (classe .hspacing) e una per gli interstizi orizzontali tra i box (classe .vspacing):

 

<style type ="text/css">

 

 

.MyBox{

 border:1px solid black;

 width:200px;

 height:50px;

 background-color:ivory;

}

 

.hspacing{

 width:auto;

}

 

.vspacing{

 height:40px;

}

 

</style>

 

Qui sotto è riportato il codice che genera una delle numerose righe della tabella. Questo codice viene ripetuto identicamente, in modo da generare tutte le linee orizzontali ciascuna composta da 4 box affiancati:

 

<table align="center" style="width:140%">

 

 <tr>

  <td

   class="MyBox"

   title="Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni.";

   align="left">

  </td>

  <td class="hspacing"></td>

  <td

   class="MyBox"

   title="Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni.";

   align="center">

  </td>

  <td  class="hspacing"></td>

  <td

   class="MyBox"

   title="Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni.";

   align="right">

  </td>

  <td class="hspacing"></td>

  <td

   class="MyBox"

   title="Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni.";

   align="center">

  </td>

 </tr>

 <tr><td class="vspacing"></td></tr>

 

..................................................................

 

</table>

 

Il tag <td> che corrisponde al box vero e proprio contiene nel campo title il testo che verrà visualizzato nella Tooltip:

 

title = "Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni. Questo è un box di informazioni."

 

Ciascuno, ovviamente, inserirà il proprio testo al posto di quello mostrato.

 

Il foglio di stile CSS della Tooltip è il seguente:

 

.tooltip {

 display:none;

 position:absolute;

 word-wrap: normal;

 width:8cm;

 height:auto;

 border:2px solid red;

 background-color:papayawhip;

 border-radius:5px;

 padding:10px;

 padding-top:4px;

 padding-bottom:5px;

 color:black;

 font-size:14px

 font-family: "Times New Roman";

 font-weight:normal;

 text-align:justify;

 text-justify:inter-word;

}

 

La tooltip non appare finché non si verifica l'evento del passaggio del mouse su uno dei box, e quindi viene dichiarata invisibile:

 

display:none;

 

Il testo al suo interno viene giustificato con le due istruzioni:

 

text-align:justify;

text-justify:inter-word;

 

Poiché la tooltip deve essere spostabile in qualsiasi parte della finestra, la sua posizione viene dichiarata assoluta:

 

position:absolute;

 

Le posizioni top e left che sono associate ad una posizione assoluta non vengono precisate: lo saranno al momento del verificarsi del passaggio del mouse su un box. A differenza del valore fixed, il valore absolute di position fissa la posizione del box rispetto al documento e non alla finestra, e quindi il box si muove (teoricamente) con lo scrolling, mentre nel caso di posizione fixed lo scrolling non modifica la sua posizione nella finestra.

 

La prima istruzione che compare nello script che si occupa di gestire le tooltip è la seguente:

 

$(document).ready(function()

 {

 .........

 .........

 .........

});

 

Si tratta di una tipica istruzione jQuery: tutto il codice jQuery viene normalmente eseguito solo dopo che il codice HTML per la visualizzazione della pagina sia stato eseguito; in altre parole solo dopo che tutti gli elementi del documento siano stati mostrati nella pagina, per impedire il malfunzionamento delle istruzioni che li manipolano.

Passiamo ora alla descrizione delle routine che gestiscono gli eventi relativi al mouse.

Quando il mouse passa su un box si attiva una funzione collegata all'evento mouseover:

 

  $('.MyBox,.MyAnchor').mouseover

  (

   function(event)

   {

    var title = $(this).attr('title');

    if(title != null && title.length > 0)

    {

     $(this).data('tipText', title);

     $(this).removeAttr('title');

     var InfoBox=$("<p class='tooltip'></p>");

     InfoBox

      .text(title)

      .appendTo($(this))

      .fadeIn('fast');

     InfoBoxWidth=InfoBox.css('width').replace("px","");

     InfoBoxHeight=InfoBox.css('height').replace("px","");

     while(InfoBoxWidth < (InfoBoxHeight*(200/100)))

     {

      InfoBoxWidth=InfoBoxWidth*(105/100);

      InfoBox.css({width:InfoBoxWidth});

      InfoBoxHeight=InfoBox.css('height').replace("px","");

      InfoBoxWidth=InfoBox.css('width').replace("px","");

     }

     document.InfoBoxWidth=InfoBoxWidth;

     document.InfoBoxHeight=InfoBoxHeight;

 

     InfoBoxOffsetX = 30;

     InfoBoxOffsetY = 40;

     RelativeToWindowMouseX=event.pageX-document.HorizontalScrollValue;

     RelativeToWindowMouseY=event.pageY-document.VerticalScrollValue;

     if(RelativeToWindowMouseY+InfoBoxOffsetY+5 > document.WindowHeight - document.InfoBoxHeight){InfoBoxOffsetY=-(InfoBoxOffsetY)-document.InfoBoxHeight;}

     if(RelativeToWindowMouseX+InfoBoxOffsetX+5 > document.WindowWidth - InfoBoxWidth){InfoBoxOffsetX=-(InfoBoxOffsetX)-InfoBoxWidth;}

     mousex=event.pageX+InfoBoxOffsetX;

     mousey=event.pageY+InfoBoxOffsetY;

     $('.tooltip').offset({top: mousey,left: mousex});

    }

   }

  );

 

Il codice jQuery per l'attivazione di una funzione al verificarsi di un evento ha la seguente struttura:

 

$('.MyBox').mouseover

(

 function(event)

 {

  ........

  ........

  ........

 }

)

   

dove $('.MyBox').mouseover rappresenta l'evento del passaggio del mouse su un elemento di classe "MyBox" e function(event){...} contiene le istruzioni che devono essere eseguite.

Si noti l'uso dell'oggetto "this", che in jQuery può rappresentare cose diverse in contesti diversi, ma qui rappresenta il box a cui si ricollega l'evento (passaggio del mouse). Perciò l'istruzione:

 

var title = $(this).attr('title');

 

legge la stringa che costituisce il valore dell'attributo "title" del box in cui si è verificato l'evento.

Se nel codice del box non è stato inserito un attributo "title":

 

<td class="MyBox"> </td>

 

ovvero se l'attributo consiste di una stringa vuota perché non è stato riempito:

 

<td class="MyBox" title=""> </td>

 

allora la funzione non esegue alcuna istruzione. Questa condizione è espressa da:

 

  if(title != null && title.length > 0){...}

 

dove le eventuali istruzioni vanno a posto dei puntini. Senza questa istruzione, quando il mouse passa su un box con title="" verrebbe visualizzata una antiestetica tooltip vuota.

La prima istruzione inserisce l'attributo 'tipText' e gli dà come valore la stringa contenuta nell'attributo titolo:

 

  $(this).data('tipText', title);

 

il metodo data(NomeElemento, dati) di jQuery collega dei dati ad un qualsiasi elemento DOM, che possono essere letti con una istruzione del tipo:

 

  $(this).data('tipText');

 

Dopo che il valore dell'attributo "title" è stato salvato in "tipText", viene rimosso l'attributo "title":

 

$(this).removeAttr('title');

 

Questo per evitare che, subito dopo che è apparsa la tooltip, compaia anche il piccolo box che Explorer associa all'eventuale presenza di un attributo "title".

Viene quindi creata la variabile InfoBox, che rappresenta un paragrafo di classe .tooltip, che è il nostro box informativo, che faremo apparire al momento giusto:

 

var InfoBox=$("<p class='tooltip'></p>");

 

Il testo che era contenuto nell'attributo "title" e che ora è nella variabile "title" viene scritto in InfoBox:

  InfoBox.text(title)

 

Il box InfoBox viene posizionato al disotto del box rappresentato dall'oggetto "this" (vale a dire dove sarebbe posizionato se il suo codice fosse posto sotto il codice del box rappresentato dalla variabile "this"):

 

InfoBox.appendTo($(this))

 

Il box InfoBox viene reso visibile:

 

InfoBox.fadeIn('fast');

 

Vengono acquisite la larghezza e l'altezza del box:

 

InfoBoxWidth=InfoBox.css('width').replace("px","");

 

InfoBoxHeight=InfoBox.css('height').replace("px","");

 

Attraverso un ciclo while vengono modificate larghezza e altezza di InfoBox in modo che la larghezza abbia misura doppia dell'altezza:

 

while(InfoBoxWidth < (InfoBoxHeight*(200/100)))

{

 InfoBoxWidth=InfoBoxWidth*(105/100);

 InfoBox.css({width:InfoBoxWidth});

 InfoBoxHeight=InfoBox.css('height').replace("px","");

 InfoBoxWidth=InfoBox.css('width').replace("px","");

}

document.InfoBoxWidth=InfoBoxWidth;

document.InfoBoxHeight=InfoBoxHeight;

 

Vengono settati i valori dello spostamento di InfoBox rispetto alla posizione del mouse:

 

InfoBoxOffsetX = 30;

InfoBoxOffsetY = 40;

 

Vengono acquisiti i valori dello scrolling verticale e dello scrolling orizzontale, cioè della distanza in pixel tra l'inizio del documento e il punto del documento che corrisponde al margine superiore della finestra (scrolling verticale) e la distanza in pixel tra il margine sinistro del documento e il punto della riga in cui inizia la visualizzazione della finestra (scrolling orizzontale):

 

RelativeToWindowMouseX=event.pageX-document.HorizontalScrollValue;

RelativeToWindowMouseY=event.pageY-document.VerticalScrollValue;

 

Viene controllato se la linea inferiore di InfoBox è all'interno della finestra:

 

if(RelativeToWindowMouseY+InfoBoxOffsetY+5 > document.WindowHeight - document.InfoBoxHeight)

{

 InfoBoxOffsetY=-(InfoBoxOffsetY)-document.InfoBoxHeight;

}

 

La posizione verticale della linea inferiore di InfoBox rispetto al lato superiore della finestra è data dalla somma della posizione del mouse rispetto all'angolo superiore della finestra (RelativeToWindowMouseY) più la distanza verticale dell'angolo superiore sinistro di InfoBox rispetto al mouse (InfoBoxOffsetY) più l'altezza di InfoBox (document.InfoBoxHeight). Se questo valore è superiore all'altezza della finestra (document.WindowHeight):

 

RelativeToWindowMouseY + InfoBoxOffsetY + document.InfoBoxHeight > document.WindowHeight

 

allora vuol dire che InfoBox fuoriesce in tutto o in parte inferiormente dalla finestra e una parte del suo contenuto non è visibile. In questo caso, InfoBox viene "ribaltato" in senso verticale: anziché essere posizionato al disotto della posizione del mouse, viene posizionato al disopra del mouse, con il margine inferiore ad una distanza dalla posizione del mouse pari in valore assoluto a quella che esisteva tra la posizione del mouse e il margine superiore di InfoBox prima della rettifica:

 

InfoBoxOffsetY=-(InfoBoxOffsetY)-document.InfoBoxHeight;

 

Viene poi controllato se la linea laterale destra di InfoBox sia all'interno della finestra:

 

if(RelativeToWindowMouseX+InfoBoxOffsetX+5 > document.WindowWidth - InfoBoxWidth)

{

 InfoBoxOffsetX=-(InfoBoxOffsetX)-InfoBoxWidth;

}

 

La posizione orizzontale della linea destra di InfoBox rispetto al lato sinistro della finestra è data dalla somma della posizione del mouse rispetto al lato sinistro della finestra (RelativeToWindowMouseX) più la distanza orizzontale dell'angolo superiore sinistro di InfoBox rispetto al mouse (InfoBoxOffsetX) più la larghezza di InfoBox  (InfoBoxWidth). Se questo valore è superiore alla larghezza della finestra (document.WindowHeight) allora vuol dire che InfoBox fuoriesce in tutto o in parte dal lato destro della finestra, e una parte del suo contenuto non è visibile. In questo caso InfoBox  viene "ribaltato" orizzontalmente: anziché essere posizionato a destra della posizione del mouse, viene posizionato a sinistra del mouse, con il margine destro ad una distanza dalla posizione del mouse pari in valore assoluto a quella che esisteva tra la posizione del mouse e il margine sinistro di InfoBox prima della rettifica:

 

InfoBoxOffsetX=-(InfoBoxOffsetX)-InfoBoxWidth;

 

Dopo questi aggiustamenti, si procede a modificare effettivamente la posizione di InfoBox:

 

mousex=event.pageX+InfoBoxOffsetX;

mousey=event.pageY+InfoBoxOffsetY;

$('.tooltip').offset({top: mousey,left: mousex});

 

Consideriamo ora il codice che viene chiamato al verificarsi dello spostamento del mouse entro uno dei box:

 

  $('.MyBox,.MyAnchor').mousemove

  (

   function(event)

   {

    InfoBoxOffsetX = 30;

    InfoBoxOffsetY = 40;

    RelativeToWindowMouseX=event.pageX-document.HorizontalScrollValue;

    RelativeToWindowMouseY=event.pageY-document.VerticalScrollValue;

    if(RelativeToWindowMouseY + InfoBoxOffsetY + 5> document.WindowHeight - document.InfoBoxHeight){InfoBoxOffsetY=-(InfoBoxOffsetY)-document.InfoBoxHeight;}

    if(RelativeToWindowMouseX+InfoBoxOffsetX + 5 > document.WindowWidth - document.InfoBoxWidth){InfoBoxOffsetX=-(InfoBoxOffsetX)-document.InfoBoxWidth;}

    mousex=event.pageX+InfoBoxOffsetX;

    mousey=event.pageY+InfoBoxOffsetY;

    $('.tooltip').offset({top: mousey,left: mousex});

   }

  );

 

Vengono settati i valori dello spostamento di InfoBox rispetto alla posizione del mouse:

 

InfoBoxOffsetX = 30;

InfoBoxOffsetY = 40;

 

Viene acquisita la posizione del mouse rispetto alla finestra (non al documento):

 

RelativeToWindowMouseX=event.pageX-document.HorizontalScrollValue;

RelativeToWindowMouseY=event.pageY-document.VerticalScrollValue;

 

La posizione orizzontale del mouse rispetto alla finestra è data dalla posizione del mouse rispetto al documento (event.pageX) meno il valore dello scrolling orizzontale (document.HorizontalScrollValue).

La posizione verticale del mouse rispetto alla finestra è data dalla posizione del mouse rispetto al documento (event.pageY) meno il valore dello scrolling verticale (document.VerticalScrollValue):

Seguono istruzioni simili a quelle che abbiamo già commentato nel caso dell'evento mouseover, per posizionare correttamente InfoBox, in modo che tutto il suo contenuto risulti in vista:

 

if(RelativeToWindowMouseY + InfoBoxOffsetY + 5> document.WindowHeight - document.InfoBoxHeight)

{

 InfoBoxOffsetY=-(InfoBoxOffsetY)-document.InfoBoxHeight;

}

if(RelativeToWindowMouseX+InfoBoxOffsetX + 5 > document.WindowWidth - document.InfoBoxWidth)

{

InfoBoxOffsetX=-(InfoBoxOffsetX)-document.InfoBoxWidth;

}

mousex=event.pageX+InfoBoxOffsetX;

mousey=event.pageY+InfoBoxOffsetY;

$('.tooltip').offset({top: mousey,left: mousex});

 

Quando il mouse esce dal box, si attiva la funzione collegata all'evento mouseout:

 

$('.MyBox,.MyAnchor').mouseout

(

 function()

 {

  $(this).attr('title', $(this).data('tipText'));

  $('.tooltip').remove();

 }

);

 

Viene ripristinato il valore dell'attributo "title" del box (che era stato rimosso quando il mouse era entrato nel box):

 

$(this).attr('title', $(this).data('tipText'));

 

Vengono rimossi i dati associati temporaneamente al box per ospitare il contenuto dell'attributo "title":

 

$('.tooltip').remove();

 

Il codice che abbiamo esaminato sinora fa riferimento in alcuni casi a valori ottenuti direttamente con metodi e proprietà jQuery, come ad esempio:

 

event.pageX

event.pageY

 

mentre in altri casi fa riferimento a variabili globali dichiarate al momento del caricamento della pagina

 

document.InfoBoxHeight=0;

document.InfoBoxWidth=0;

document.WindowHeight=window.innerHeight;

document.WindowWidth=window.innerWidth;

document.VerticalScrollValue=0;

document.HorizontalScrollValue=0;

document.RelativeToWindowMouseX=0;

document.RelativeToWindowMouseY=0;

 

Alcune di queste variabili sono acquisite al caricamento del documento e non cambiano:

 

document.WindowHeight=window.innerHeight;

document.WindowWidth=window.innerWidth;

 

Altre variabili sono ricalcolate ad ogni spostamento del mouse tramite apposite istruzioni:

 

document.WindowHeight=window.innerHeight;

document.WindowWidth=window.innerWidth;

document.VerticalScrollValue=0;

document.HorizontalScrollValue=0;

document.RelativeToWindowMouseX=0;

document.RelativeToWindowMouseY=0;

 

L'altezza e larghezza di InfoBox vengono aggiornate, nella routine mouseover, una volta che le proporzioni di InfoBox sono state modificate con il ciclo while che abbiamo già commentato:

 

while(InfoBoxWidth < (InfoBoxHeight*(200/100)))

{

 InfoBoxWidth=InfoBoxWidth*(105/100);

 InfoBox.css({width:InfoBoxWidth});

 InfoBoxHeight=InfoBox.css('height').replace("px","");

 InfoBoxWidth=InfoBox.css('width').replace("px","");

}

document.InfoBoxWidth=InfoBoxWidth;

document.InfoBoxHeight=InfoBoxHeight;

 

La posizione del mouse rispetto alla finestra viene calcolata entro la routine mouseover e la routine mousemove:

 

RelativeToWindowMouseX=event.pageX-document.HorizontalScrollValue;

RelativeToWindowMouseY=event.pageY-document.VerticalScrollValue;

 

E questo è tutto.

attenzione: Se volete automatizzare le operazioni di inserzione delle informazioni nel campo "title", scrivendole in un documento XML e inserendole nel tag al momento del caricamento della pagina, consultate in questo documento l'articolo "Inserire nel campo 'title' dei vostri link le informazioni visualizzate dal browser al passaggio del mouse utilizzando XML, javascript e php"

 

 

 

Inserire nel campo "title" dei vostri link, al caricamento della pagina, informazioni che verranno visualizzate dal browser al passaggio del mouse, utilizzando XML, javascript e php

back to Index

 

 

Tutti i principali browser dispongono di una funzionalità che verifica se un tag disponga al suo interno di un campo "title" e in caso affermativo fa apparire, dopo una frazione di secondo, un minuscolo box informativo con la stringa inserita in "title". Ad esempio, nel caso del seguente tag:

 

<a title="Questa è la pagina del principale giornale statunitense online" href="usatoday.com">USA Today</a>

 

al passaggio del mouse sul link apparirà un piccolo box con la spiegazione: "Questa è la pagina del principale giornale statunitense online".

Se volete che tutti i vostri link siano dotati di un simile box informativo, dovreste inserire un campo "title" in ciascuno di essi, seguito da una stringa illustrativa.

Questo crea qualche difficoltà nel momento in cui volete aggiornare la descrizione di qualche link, perché dovrete aprire con un editor il codice della pagina internet, cercare al suo interno il link - che non è facile quando essa ne contiene parecchie decine - e modificare l'attributo "title", salvando poi il tutto. Inoltre, se le descrizioni sono lunghe, questo affollerà di stringhe il codice HTML rendendolo poco leggibile.

L'alternativa che vi proponiamo qui è di dotare ogni tag <a> di un id univoco che consente di capire immediatamente di quale link si tratti, e di raccogliere tutte le descrizioni in un file XML posto sullo stesso server dove è la vostra pagina web, dove ognuna di esse è facilmente ritrovabile, perché associata all'id del link. Ogni tag <a> avrebbe allora un id e un campo "title" vuoto:

 

<a id="UsaToday" title="" href="usatoday.com">USA Today</a>

 

Per vedere all'opera questo sistema, apriamo la pagina TitlesLoadingExample.htm, e osserviamone il codice.

Entro una tabella abbiamo 4 box il cui codice è (in questo caso si tratta del Box 1):

 

<td id="Box1"  class="MyBox" title="">

 BOX 1

</td>

 

Come si vede l'attributo "title" esiste ma è vuoto. Esso è destinato ad essere riempito con la stringa "Questo e' il Box 1" contenuta nel file titles.xml. In altre parole, il testo da visualizzare nella tooltip, anziché inserito nel codice della pagina html entro il tag con l'istruzione title = "…" viene, più ordinatamente, letto da una routine javascript/jQuery dal file titles.xml al momento del caricamento della pagina:

 

<?xml version='1.0' encoding='utf-8'?>

<documenti>

 

<documento>

  <titolo>Box1</titolo>

  <presentazione>

   Questo e' il Box 1

  </presentazione>

</documento>

 

<documento>

  <titolo>Box2</titolo>

  <presentazione>

   Questo e' il Box 2

  </presentazione>

</documento>

 

<documento>

  <titolo>Box3</titolo>

  <presentazione>

   Questo e' il Box 3

  </presentazione>

</documento>

 

<documento>

  <titolo>Box4</titolo>

  <presentazione>

   Questo e' il Box 4

  </presentazione>

</documento>

 

<documento>

  <titolo>Box5</titolo>

  <presentazione>

   Questo e' il Box 5

  </presentazione>

</documento>

 

</documenti>

 

Ecco il codice ajax che consente di leggere il file xml in cui sono contenuti i testi da inserire nei campi "title":

 

<script type="text/javascript">

 

 function FillTitleAttribute()

 {

  var mozillaFlag = false;

  var XMLHttpRequestObject = false;

  if (window.XMLHttpRequest)

  {

   XMLHttpRequestObject = new XMLHttpRequest();

   XMLHttpRequestObject.overrideMimeType("text/xml");

   mozillaFlag = true;

  }

  else if (window.ActiveXObject)

  {

   XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

  }

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "titles.xml", true);

   XMLHttpRequestObject.setRequestHeader('Content-Type', 'text/xml');

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     var xmlDocument = XMLHttpRequestObject.responseXML;

     if(mozillaFlag)

     {

      removeWhitespace(xmlDocument);

     }

     WriteTitles (xmlDocument);

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

 

 function WriteTitles(xmldoc)

 {

  var documenti = xmldoc.documentElement;

  var LoopIndex;

  var BoxName;

  for(LoopIndex = 0; LoopIndex<documenti.childNodes.length; LoopIndex++)

  {

   BoxName=documenti.childNodes[LoopIndex].firstChild.firstChild.nodeValue;

   if (document.getElementById(BoxName) != null && documenti.childNodes[LoopIndex].lastChild.firstChild.nodeValue.length > 8)

   {

    try

    {

     document.getElementById(BoxName).attributes["title"].value=documenti.childNodes[LoopIndex].lastChild.firstChild.nodeValue;

    }

    catch(err){}

   }

  }

 }

 

 function removeWhitespace(xml)

 {

  var loopIndex;

  for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++)

  {

   var currentNode = xml.childNodes[loopIndex];

   if (currentNode.nodeType == 1)

   {

    removeWhitespace(currentNode);

   }

   if (((/^\s+$/.test(currentNode.nodeValue))) && (currentNode.nodeType == 3))

   {

    xml.removeChild(xml.childNodes[loopIndex--]);

   }

  }

 }

 

</script>

 

La funzione FillTitleAttribute() viene richiamata al caricamento della pagina mediante l'istruzione:

 

<body onload="FillTitleAttribute();">

 

La funzione FillTitleAttribute() acquisisce con una chiamata asincrona il file titles.xml, ne elimina gli spazi e i ritorni a capo che potrebbero provocare malfunzionamenti, richiamando la funzione removeWhitespace(xml), e poi passa il documento alla funzione WriteTitles(xmldoc) perché riempia i campi "title".

Il codice, dopo aver letto il documento titles.xml, entra in un loop che scorre uno alla volta gli elementi <documento>...</documento> di titles.xml, ne legge il campo <titolo>...</titolo> e se trova un tag di TitlesLoadingExample.htm che ha l'attributo "id" coincidente, provvede a riempire l'attributo "title" con l'istruzione:

 

document.getElementById($(this).find('titolo').text()).attributes['title'].value=$(this).find('presentazione').text();

 

Quando non esiste un tag di TitlesLoadingExample.htm con l'identificativo corrispondente a quello letto nel file titles.xml viene generato errore, ma l'errore è catturato dalle istruzioni:

 

try

{

 document.getElementById(BoxName).attributes["title"].value=documenti.childNodes[LoopIndex].lastChild.firstChild.nodeValue;

}

catch(err){}

 

in modo che il programma non si arresti e il loop prosegua.

 

Il codice per leggere il file xml funziona sia client-side (sul vostro computer non collegato alla rete) sia server-side (con la pagina html e il file xml sul server).

Nel caso di un sito internet è di poca utilità un codice che funziona in locale sul vostro computer, ma è tuttavia utile per il debugging, perché per testarne il funzionamento non è necessario rifarne ogni volta l'upload.

 

Ecco la versione del codice utilizzando invece jQuery:

 

<script type="text/javascript">

 $(document).ready(function()

 {

  $.get("titles.xml",function(xmlDoc)

  {

   $(xmlDoc).find('documento').each

   (

    function()

    {

     try

     {

      document.getElementById($(this).find('titolo').text()).attributes['title'].value=$(this).find('presentazione').text();

     }

     catch(err){}

    }

   );

  },"xml");

 });

</script>

 

Vi proponiamo infine un terzo modo di inserire il testo di titles.xml nei tag che si vogliono dotare di tooltip, nella pagina TitlesLoadingExample.php  (cliccate per visualizzarla) mediante codice php.

Osserviamo la diversa struttura di uno dei box nel <body> del documento:

 

<tr>

 <td  <?W('Box1');?> class="MyBox">

  BOX 1

 </td>

</tr>

 

Come si vede, invece dell'attributo title = " ... " si ha un frammento di codice php:

 

<?W('Box1');?>

 

che richiama la funzione W($NomeFile) definita nell'<head> della pagina:

 

<?php

 function W($NomeFile)

 {

  $title = simplexml_load_file('titles.xml');

  $MyArray=$title->xpath('//documento[titolo="'.$NomeFile.'"]');

  $presentazione = $MyArray[0]->presentazione;

  print("title=\"".$presentazione."\"");

 }

?>

 

la quale apre il file ToolTipText.xml, cerca l'elemento <documento>…</documento> il cui titolo coincide con la stringa passata come argomento e provvede a scrivere entro il tag <td>…</td> la seguente stringa:

 

title="..."

 

dove il contenuto di title è il campo <presentazione>…</presentazione> dell'elemento di ToolTipText.xml.

In tal modo la pagina html viene inviata dal server al vostro computer già completa con gli attributi "title" riempiti.

Ricordiamo che anche in questo caso il file ToolTipPage.php non funziona sul vostro computer, ma su un server php, e quindi per vederla dovete farne l'upload sul vostro server o installare un server php sul vostro computer.

 

 

 

Alcune cose che javascript non fa o fa solo a prezzo di una programmazione complicata e poco pulita

back to Index

 

 

Javascript non può assolutamente scrivere o leggere dei files che sono sul client, cioè sull'hard-disk dell'utente a cui viene inviata la pagina web, e ciò per ovvi motivi di sicurezza.

L'unica maniera di memorizzare dati è nelle variabili della pagina, dando loro nomi come window.MyVariable o document.MyVariable, oppure in qualche attributo di un tag (ad es. nell'attributo title o nell'attributo value di un box di testo con la qualità "display:hidden", che risulta nascosto all'utente, ma è leggibile da javascript.

Ma questi dati spariranno con la chiusura della sessione web.

Altri dati possono essere scritti nei cookies, e possono rimanere sul computer ospite, ma non tutti i computer accettano cookies, e quindi il codice scritto basandosi suo cookies è assolutamente inaffidabile

 

Far aprire un documento nella stessa finestra da cui lo si richiama con il comando:

 

window.open("NomeFile");

 

è estremamente difficile: il documento si apre immancabilmente in un'altra finestra. A meno che non abbiate diverse ore da perdere o un suggerimento funzionante di un programmatore esperto (che chi scrive non ha trovato), lasciate perdere per il momento.

 

I box di messaggio javascript sono molto rudimentali; ad esempio nel box di input che compare con la seguente istruzione:

 

Password = prompt("DIGITA LA PASSWORD","");

 

non è possibile modificare l'avviso "la pagina all'indirizzo… dice:" che precede il testo del nostro prompt, né è possibile cambiare la modalità di inserimento di una parola entro il box in modo che durante la digitazione della password vengano mostrati solo asterischi.

 

Malgrado abbia ottime funzionalità di gestione di un file XML, javascript non può caricarlo direttamente, ma lo deve trovare come variabile globale della pagina, e procurarglielo in questa forma è alquanto laborioso, e richiede l'uso di altri linguaggi (ad esempio php e ajax)

 

 

 

Una pagina php che cambia aspetto ogni volta che la si ricarica

back to Index

 

 

Aprite la pagina IndexRandom.php e date un'occhiata al codice, riportato qui sotto (in particolare agli script php, che non compaiono nel codice della pagina web):

 

<html>

<head>

<?php

 function DisplayTitle($elemento)

 {

  $nomi = array("DI BIANCANEVE", "DELLA STREGA CATTIVA", "DEL PRESIDE DELLO SRAFFA", "DI MATTEO RENZI", "DI SILVIO BERLUSCONI");

  $azioni=array("STO FACENDO BUNGA-BUNGA", "SONO IN BAGNO CON GRAVI PROBLEMI", "SONO OFFLINE", "STO RIPARANDO LA MOTOZAPPA");

  if($elemento=="nome")

  {

   $NumeroCasuale=rand(0,4);

   print($nomi[$NumeroCasuale]);

  }

  elseif ($elemento=="azione")

  {

   $NumeroCasuale=rand(0,3);

   print("$azioni[$NumeroCasuale]");

  }

 }

?>

</head>

<body>

</br></br>

<div style="text-align:center;font-size:200%;font-weight:bold;">

BENVENUTO! QUESTO E' IL SITO <?php DisplayTitle('nome'); ?>

</br></br>

AL MOMENTO <?php DisplayTitle('azione'); ?>.

</br></br>

 RIPASSA PIU' TARDI.

</div>

</body>

</html>

 

La funzione DisplayTitle sceglie a caso un elemento dell'array $nomi e uno dell'array $azioni e lo restituisce tramite l'istruzione:

 

print("$nomi[$NumeroCasuale]");

print("$azioni[$NumeroCasuale]");

 

al codice che, nel messaggio di benvenuto, la richiama.

In questo modo, ogni volta che si ricarica la pagina, appare una scritta diversa.

 

 

 

Un codice php per consentire agli utenti del vostro sito il download di qualsiasi tipo di file

back to Index

 

 

Per il download di file .doc, .pdf, .xls dal vostro sito è sufficiente inserire il nome del file, ed esso sarà scaricato correttamente:

 

<a target="_parent" href="MyFile.xls">Clicca qui per scaricare MyFile</a>

 

Ma quando si mettono sul server files .htm o .php o .xml il download non viene effettuato correttamente. Per operare il download di questi file è necessario creare un file download.php che contiene il seguente codice:

 

<?php

// Recupero il nome del file dalla querystring

// e lo accodo al percorso della cartella del download

$file = (isset($_GET['filename']) ? $_GET['filename'] : false);

 

// verifico che il file esista

if (!file_exists($file))

{

  // se non esiste stampo un errore

  echo "Il file non esiste!";

}else{

  // Se il file esiste...

  // Imposto gli header della pagina per forzare il download del file

  header("Cache-Control: public");

  header("Content-Description: File Transfer");

  header("Content-Disposition: attachment; filename= " . $file);

  header("Content-Transfer-Encoding: binary");

  // Leggo il contenuto del file

  readfile($file);

}

?>

 

Nella pagina html, il link per scaricare ad esempio il file MyFile.htm dovrà essere il seguente:

 

<a target="_parent" href="download.php?filename=MyFile.htm">Clicca qui per scaricare MyFile</a>

 

Errore da principianti: il file download.php, per funzionare, deve essere sul server. Se fate una prova del codice con download.php che è nella directory del sito che avete sul vostro hard disk, quello che viene scaricato è… il file download.php.

 

 

 

Una pagina in cui una routine php genera una tabella che mostra il contenuto di un database

back to Index

 

 

Aprite la pagina Experiments2.htm . Date un'occhiata al codice con l'opzione "visualizza sorgente pagina" del tasto destro del mouse (per Explorer l'opzione è "HTML"):

 

<html>

<head>

 

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">

</script>

 

<script language="javascript">

 

$(document).ready(function()

{

 

 $('#MostraAutoreButton').prop('checked',true);

 $('#NonMostrareAutoreButton').prop('checked',false);

 

});

 

function GetPoems()

{

 var DisplayResults = "";

 if ($('#MostraAutoreButton').prop('checked')){DisplayAuthor="true";}else{DisplayAuthor="false";}

 $.get("GetPoems.php?DisplayAuthor="+DisplayAuthor,function(result54){$('#DisplayResults').html(result54);},"text");

}

 

</script>

 

</head>

<body onload="GetPoems();">

 

</br></br>

 

<table align="center" style="text-align:left;width:250px;border:1px solid black;">

 <tr>

  <td>

   <input align="center" id="MostraAutoreButton" type="radio" name="MostraAutore" value ="enabled">Mostra l'autore

   </br>

   <input id="NonMostrareAutoreButton" type="radio" name="MostraAutore" value ="disabled">Non mostrare l'autore

  </td>

 </tr>

</table>

 

</br></br>

 

<table align="center">

 <tr>

  <td>

   <form name="RefreshForm" action="">

    <input type="button" value="REFRESH" onclick="GetPoems();"/>

   </form>

  </td>

 </tr>

</table>

 

</br></br>

 

<div id="DisplayResults">

</div>

 

</body>

</html>

 

Al caricamento del documento (e ogni volta che viene premuto il bottone "refresh") viene chiamata la funzione GetPoems(), che a sua volta chiama in modo asincrono il file GetPoems.php presente sul server, che contiene il seguente codice:

 

<?php

 

 //VENGONO ACQUISITI I PARAMETRI

 $FlagDisplayAuthor=(string)$_GET['DisplayAuthor'];

 

 //CONNESSIONE AL DATABASE

 $host = 'localhost';

 $user = 'learningsources';

 $database = 'my_learningsources';

 $password = '';

 $MyTable = "Haiku";

 $db=mysql_connect($host,$user,$password);

 mysql_select_db($database,$db);

 //SELEZIONA IL RECORD IN BASE ALLA CONDIZIONE PASSATA COME PARAMETRO

 $query="select * FROM Haiku";

 $dbResult=mysql_query($query,$db);

 $AffectedRows=mysql_numrows($dbResult);

 

 //SE ESISTE IL RECORD CORRISPONDENTE ALLA QUERY, GENERA LA TABELLA

 if ($AffectedRows>0)

 {

  echo "<table align='center' style='border:1px solid blue;background-color:blue;border:1px solid blue;'>";

  if($FlagDisplayAuthor=="true")

  {

   echo "<td align='center' valign='top' style='color:red;border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>AUTORE</td>";

   echo "<td align='center' valign='top' style='color:red;border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>HAIKU</td>";

  }

  else

  {

   echo "<td align='center' valign='top' style='color:red;border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>HAIKU</td>";

  }

  while($row = mysql_fetch_array($dbResult))

  {

   echo "<tr>";

   if($FlagDisplayAuthor=="true")

   {

    echo "<td align='center' style='border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>".$row['Autore']."</td>";

    echo "<td align='center' style='border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>".$row['Testo']."</td>";

   }

   else

   {

    echo "<td align='center' style='border:1px solid blue;background-color:white;font-size:150%;font-family:Times New Roman;padding-left:20px;padding-right:20px;padding-top:15px;padding-bottom:15px;font-weight:bold;'>".$row['Testo']."</td>";

   }

   echo "</tr>";

  }

  echo "</table>";

 }

 //CHIUDE IL DATABASE

 mysql_close($db);

 

?>

 

Questo codice php si collega alla tabella "Haiku" del database "my_learningsources" presente sul server altervista.org e invia indietro tramite la funzione "echo" il testo delle poesie e l'autore, incapsulandoli nelle righe di una tabella (pure generata con la funzione "echo"). Queste righe vengono visualizzate come contenuto del tag:

 

<div id="DisplayResults">

</div>

 

Tramite l'istruzione ajax:

 

$.get("GetPoems.php?DisplayAuthor="+DisplayAuthor,function(result54){$('#DisplayResults').html(result54);},"text");

 

Se il bottone "Mostra Autore" è stato selezionato, il parametro "DisplayAuthor" passato alla routine php è "true", e viene generata anche la colonna corrispondente all'autore.

 

 

 

Come importare una tabella Access nel database MySQL del vostro server, utilizzando XML e php

back to Index

 

 

Per compiere questa operazione sfrutteremo una utile funzionalità dei database Access, che possono esportare il contenuto di una tabella in formato XML.

 

Creiamo anzitutto nel nostro database MySQL una tabella di prova, che denomineremo "Haiku", i cui campi sono:

 

Indice (smallint(6), autoincremento, chiave primaria)

Autore (TEXT, 512 caratteri)

Epoca (TEXT, 512 caratteri)

Paese (TEXT, 512 caratteri)

Soggetto (TEXT, 1024 caratteri)

Testo (TEXT, 65535 caratteri)

 

Creiamo nel nostro database Access una tabella di prova, che denomineremo "Haiku", i cui campi sono:

 

Indice (intero lungo, autoincremento, chiave primaria)

Autore (testo breve, 255 caratteri)

Epoca (testo breve, 255 caratteri)

Paese (testo breve, 255 caratteri)

Soggetto (testo breve, 255 caratteri)

Testo (testo lungo)

 

Apriamo la tabella "Haiku" in Access e nel menu "dati esterni" selezioniamo l'opzione "File XML" e seguiamo le istruzioni per generare il file.

L'esportazione opera solo sui record selezionati, e questo vi permette di scegliere quelli da trasferire operando un filtraggio sulla tabella Access.

Se volete eliminare dei campi, l'unico modo è creare una copia della tabella e rimuovere i campi dalla sua struttura; altrimenti l'esportazione creerà delle intestazioni XML anche per i cambi indesiderati.

Vi consiglio di non rimuovere i caratteri speciali con cui Access sostituisce le vocali accentate e altri caratteri critici per XML e HTML, perché a quanto mi risulta le sigle immesse al loro posto vengono tradotte perfettamente dal browser.

Se il codice php non dovesse funzionare, controllate anzitutto che nel file XML non vi siano caratteri come apici o virgolette, che devono essere introdotti preceduti dal backslash:  \' , \" .

L'unica pecca è che nell'esportazione in XML vengono persi i caratteri CR (ritorno a capo).

Nel nostro esempio di prova noi abbiamo già generato un output XML nel file Haiku.xml (clicca per scaricarlo).

 

Creiamo il file EsportaDatabase.php (clicca per scaricarlo) inserendovi il seguente codice:

 

<?php

 

//CREA LE VARIABILI CON I NOMI DEI CAMPI

$FNameAutore='Autore';

$FNameEpoca='Epoca';

$FNamePaese='Paese';

$FNameSoggetto='Soggetto';

$FNameTesto='Testo';

 

//CONNESSIONE AL DATABASE

$host = 'localhost';

$user = 'BlogName';

$password = '';

$database = 'my_BlogName';

$tabella = 'Haiku';

$db=mysql_connect($host,$user,$password)

or die("Impossibile connettersi al server $host");

mysql_select_db($database,$db)

or die("Impossibile connettersi al database $database");

 

//ACQUISISCE I VALORI DA IMMETTERE NEL DATABASE

$ITEMS = simplexml_load_file('Haiku.xml') or die("ERROR");

foreach($ITEMS->children() as $item)

{

 echo $item->Indice."</br>";

 $FValueAutore=$item->Autore;

 $FValueEpoca=$item->Epoca;

 $FValuePaese=$item->Paese;

 $FValueSoggetto=$item->Soggetto;

 $FValueTesto=$item->Testo;

 $sql = "

  INSERT INTO $tabella(

   $FNameAutore,

   $FNameEpoca,

   $FNamePaese,

   $FNameSoggetto,

   $FNameTesto)

  VALUES(

   '$FValueAutore',

   '$FValueEpoca',

   '$FValuePaese',

   '$FValueSoggetto',

   '$FValueTesto')";

 

 $dbResult=mysql_query($sql,$db);

}

 

//CHIUDE IL DATABASE

mysql_close($db);

 

?>

 

In questo esempio abbiamo denominato il nome dell'ipotetico sito "BlogName" e il nome del database "my_BlogName"

Trasferite sul server il file EsportaDatabase.php

Digitate sulla barra degli indirizzi del vostro browser il seguente indirizzo:

 

 "BlogName.altervista.org/EsportaDatabase.php"

 

Premendo il pulsante "vai" Il file php verrà immediatamente eseguito sul server, e al vostro browser verrà inviata una copia della pagina generata con la funzione "echo", che lista il numero identificativo dei record trasferiti, per consentirvi di controllare il buon esito dell'operazione. E questo è tutto: in pochi secondi i record sono stati trasferiti sul database del vostro sito.

 

 

 

Alcune cose che php non fa, anche se sembrerebbe possibile

back to Index

 

 

Php non ha accesso agli elementi del documento, né in lettura né per modificarli. Non possiede un modello DOM analogo a quello di javascript.

Per la verità è possibile caricare una immagine xml della pagina che php legge, ma gli è impossibile modificare gli elementi della pagina tramite riferimenti DOM.

Ricordate sempre che javascript inizia a funzionare solo dopo che è stato eseguito il codice php, e quindi le funzioni php non sono accessibili a javascript e quelle javascript non sono accessibili a php (sebbene php possa modificarne il testo).

 

 

 

Introduzione ad ajax

back to Index

 

 

Ajax è l'acronimo di Asynchronous JavaScript and XML, ed è un insieme di tecniche per creare siti web altamente interattivi e applicazioni web. Una delle tecniche più importanti e caratteristiche di ajax è quella che combina le risorse di vari linguaggi per ottenere l'aggiornamento della pagina web usando dati scaricati da internet, senza il refresh della finestra del browser (asynchronous data retrieval).

Oltre a questa, ajax comprende le tecniche più potenti che impiegano XML, CSS, il DOM javascript, in combinazione tra loro per creare una pagina web altamente dinamica. In altre parole, ajax non è un nuovo linguaggio di programmazione, ma piuttosto un insieme di tecniche che utilizza linguaggi esistenti per ottenere risultati nuovi o più sofisticati di quelli che si potrebbe ottenere dall'impiego dei singoli linguaggi. Il linguaggio-base che collega tutte le varie parti di una applicazione ajax è javascript.

La potenzialità più sofisticata e distintiva di ajax è, come abbiamo detto, quella che ottiene dei dati dal sito che ha inviato la pagina o da altre fonti su internet e li fa apparire sulla pagina senza bisogno di refresh e senza che la pagina si blocchi durante il download dei dati. Una delle prime applicazioni ajax di tal genere si è avuta per la posta elettronica, ed è stata implementata da Google: ogni volta che arrivava una nuova mail nella casella che l'utente aveva aperto, veniva aggiornata solo la sezione della finestra contenente la mail, con notevole risparmio di kilobyte da parte della connessione internet dell'utente. Anche le chat visualizzano ciò che gli altri utenti hanno scritto nella vostra pagina e ciò che voi avete scritto sulle pagine degli altri utenti senza nessun refresh dello schermo. Anche le tecniche di drag-and-drop che consentono alle applicazioni più avanzate come ad esempio Mosaic di trascinare un oggetto da un sito internet sulla propria pagina utilizzano ajax per comunicare cosa ajax deve scaricare dal sito e dove deve visualizzarlo. Anche le immagini possono essere cambiate, modificando la sorgente senza cambiare l'intera pagina. Giochi online come i giochi degli scacchi modificano l'aspetto della scacchiera senza modificare altri elementi della pagina grazie ad ajax.

Per vedere ajax all'opera, apriamo il file AjaxExample1.htm e clicchiamo sul bottone che vi appare: il messaggio nel box cambierà, e verrà visualizzato il testo: "Welcome to Ajax!". Questo testo è contenuto nel file data.txt, che è posto sul server. Analizziamo il codice della pagina:

 

<html>

<head>

<script language = "javascript">

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData(dataSource, divID)

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "data.txt");

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     document.getElementById("targetParagraph").innerHTML = XMLHttpRequestObject.responseText;

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

</head>

<body>

 

  </br>

  <p style="text-align:center;font-size:120%;font-weight:bold;">Un esempio di acquisizione di dati in modo asincrono da parte del browser tramite ajax</p>

 

  </br></br>

 

  <form style="text-align:center;">

    <input type = "button" value = "Acquisisci il messaggio" onclick = "getData();">

  </form>

 

  </br></br>

 

  <div align="center">

    <p id="targetParagraph" style="font-size:110%;color:red;border:1px solid black;height:40px;width:400px;margin:auto;padding-top:20px;padding-bottom:0px;">Il messaggio acquisito apparirà qui</p>

  </div>

 

</body>

</html>

 

Il paragrafo destinato ad ospitare i dati acquisiti in modo asincrono da data.txt è il paragrafo "targetParagraph":

 

  <div align="center">

    <p id="targetParagraph" style="font-size:110%;color:red;border:1px solid black;height:40px;width:400px;margin:auto;padding-top:20px;padding-bottom:0px;">Il messaggio acquisito apparirà qui</p>

  </div>

 

La funzione getData() viene richiamata con la seguente istruzione, inserita nel tag <button>:

 

onclick = "getData();"

 

Le istruzioni, contenute nella funzione getData, che trasferiscono i dati nel paragrafo sono:

 

document.getElementById("targerParagraph").innerHTML = XMLHttpRequestObject.responseText;

 

Ma come viene acquisito il contenuto di data.txt? Viene anzitutto creato l'oggetto di classe XMLHttpRequest, che serve a JavaScript a comunicare con il server e a scaricare dati dal server:

 

var XMLHttpRequestObject = false;

if (window.XMLHttpRequest)

{

 XMLHttpRequestObject = new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

 XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

}

 

L'oggetto viene posto in una variabile globale chiamata XMLHttpRequestObject. L'oggetto XMLHttpRequest è disponibile come oggetto javascript in tutti i browser, ma è differente il modo di accedervi da browser a browser. Netscape Navigator, Safari versione 1.2 e successive e Firefox permettono di creare un oggetto XMLHttpRequest direttamente con l'istruzione:

 

XMLHttpRequestObject = new XMLHttpRequest();

 

Questo implica che esista l'oggetto window.XMLHttpRequest, e quindi la possibilità di crearlo per tal via può essere testata con l'istruzione condizionale:

 

if(window.XMLHttpRequestObject) {…}

 

Nel caso di Internet Explorer, Microsoft, come sempre, fa a modo suo, e richiede una istruzione diversa:

 

XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 

Una volta creati questi oggetti, almeno per le funzionalità di base, funzionano allo stesso modo in tutti i browser.

Ecco i metodi dell'oggetto XMLHttpRequest di Internet Explorer:

 

proprietà

descrizione

onreadystatechange

Contiene il nome del gestore di eventi che deve essere chiamato quando il valore della proprietà

readyState cambia (lettura/scrittura)

readyState

Contiene lo stato della richiesta (lettura)

responseBody

Contiene il corpo della risposta risposta. E' uno dei modi in cui una richiesta HTTP può essere eseguita

responseStream

Contiene uno stream binario di risposta alla richiesta HTTP (lettura)

responseText

Contiene il corpo della risposta come stringa (lettura)

responseXML

Contiene il corpo della risposta come documento XML (lettura)

status

Contiene il codice HTTP di status restituito in seguito a una richiesta (lettura)

statusText

Contiene lo status della risposta come testo (lettura)

 

metodo

descrizione

abort

abortisce la richiesta HTTP

getAllResponseHeaders

restituisce gli headers HTTP

getResponseHeader

restituisce il valore di un header HTTP

open

apre una richiesta al server

send

invia una richiesta al server

setRequestHeader

setta il nome e il valore di un header HTTP

 

Ecco le proprietà e metodi dell'oggetto XMLHttpRequest per Firefox e NetScape Navigator

 

proprietà

descrizione

channel

Contiene il canale utilizzato per effettuare la richiestra (lettura)

readyState

Contiene lo stato della richiesta (lettura)

responseText

Contiene il corpo della risposta come stringa (lettura)

responseXML

Contiene il corpo della risposta come documento XML (lettura)

status

Contiene il codice HTTP di status restituito in seguito a una richiesta (lettura)

statusText

Contiene lo status della risposta come testo (lettura)

 

metodo

descrizione

abort

abortisce la richiesta HTTP

getAllResponseHeaders

restituisce gli headers HTTP

getResponseHeader

restituisce il valore di un header HTTP

openRequest

metodo nativo (nonscript) per aprire una richiesta al server

overrideMimeType

bypassa il tipo MIME che il server restituisce

 

Ecco le proprietà e metodi dell'oggetto XMLHttpRequest per Safari:

 

proprietà

descrizione

onreadystatechange

Contiene il nome del gestore di eventi che deve essere chiamato quando il valore della proprietà

readyState cambia (lettura/scrittura)

readyState

Contiene lo stato della richiesta (lettura)

responseText

Contiene il corpo della risposta come stringa (lettura)

responseXML

Contiene il corpo della risposta come documento XML (lettura)

status

Contiene il codice HTTP di status restituito in seguito a una richiesta (lettura)

statusText

Contiene lo status della risposta come testo (lettura)

 

metodo

descrizione

abort

abortisce la richiesta HTTP

getAllResponseHeaders

restituisce gli headers HTTP

getResponseHeader

restituisce il valore di un header HTTP

open

apre una richiesta al server

send

invia una richiesta al server

setRequestHeader

setta il nome e il valore di un header HTTP

 

Al caricamento del documento il browser cerca di creare, secondo le istruzioni, un oggetto XMLHttpRequest. Il codice che segue, contenuto nella funzione getData(), controlla anzitutto che la variabile sia stata creata con successo, e solo in quel caso procede all'esecuzione delle istruzioni ajax:

 

if(XMLHttpRequestObject)

{

.........

.........

.........

}

 

A questo scopo la variabile XMLHttpRequestObject è inizializzata con il valore false, in modo che, se non si è avuto successo nel crearla, l'istruzione sopra riportata dà come valore "false"

Se l'oggetto è stato creato, esso viene aperto:

 

XMLHttpRequestObject.open("GET", dataSource);

 

La struttura del metodo .open è la seguente (i parametri opzionali sono compresi tra parentesi quadre):

 

open(metodo, URL, [asyncFlag], [userName], [password])

 

ecco una spiegazione dei parametri:

 

metodo

il metodo HTTP utilizzato per aprire la connessione

(GET, POST, PUT, HEAD, PROPFIND)

URL

l'URL da contattare quando ci si connette col server

asyncFlag

un valore booleano che indica se la chiamata è asincrona (default: true)

userName

lo username del proprio account

password

la password utilizzata per collegarsi al proprio account

 

Nel nostro esempio il metodo scelto per contattare il server è il metodo "GET" (che è il modo usuale di contattare i server). L'URL è passata alla funzione tramite il parametro dataSource. Il metodo open configura l'oggetto XMLHttpRequest, ma non apre ancora alcuna connessione col server.

L'URL si può riferire non solo ad un file di dati, ma anche ad un file che contiene uno script php destinato a recuperare/creare i dati. L'URL si può riferire a un file che è sullo stesso server su cui è la pagina HTML che utilizza il codice ajax, oppure ad un server estraneo che mette a disposizione la risorsa cercata (ad es. Google mette a disposizione i suoi notiziari o il risultato di una ricerca in formato XML o Json).

Il processo è asincrono (valore di default) non solo nel senso che alla sua conclusione non avviene il refresh dell'intera pagina, ma anche nel senso che la pagina non si blocca in attesa che il download dei dati sia completato: l'utente può continuare ad interagire con essa mentre esso viene effettuato.

Ajax segnala al browser che il download si è concluso mediante la proprietà XMLHttpRequestObject.onreadystatechange, che attiva una funzione di callback quando si verifica una variazione qualsiasi nello stato del download (inizio del download, download già iniziato, completamento del download ecc.).

 

XMLHttpRequestObject.onreadystatechange = function() {...}

 

In realtà, la proprietà onreadystatechange segnala solo che la variabile di stato XMLHttpRequestObject.readyState, che esprime la situazione del download ha subito un mutamento: occorre verificare che il cambiamento coincide con il completamento del download, verificando la proprietà XMLHttpRequestObject.readyState e la proprietà XMLHttpRequestObject.status:

 

if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

 

Ecco un prospetto dei valori che può assumere la proprietà readyState:

 

0

Unitialized

1

Loading

2

Loaded

3

Interactive

4

Complete

 

Ecco un prospetto dei valori che può assumere la proprietà status:

 

200

OK

201

Created

204

No Content

205

Reset Content

206

Partial Content

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

405

Method Not Allowed

406

Not Acceptable

407

Proxy Authentication Required

408

Request Timeout

411

Length Required

413

Requested Entity Too Large

414

Requested URL Too Long

415

Unsupported Media Type

500

Internal Server Error

501

Not Implemented

502

Bad Gateway

503

Service Unavailable

504

Gateway Timeout

505

HTTP Version Not Supported

 

Il verificarsi della condizione XMLHttpRequestObject.readyState == 4 ("download completato") non è sufficiente: occorre testare la condizione XMLHttpRequestObject.status == 200 ("download effettuato con successo") per poter iniziare a lavorare con i dati.

Prima che l'istruzione contenuta nella funzione di callback sia eseguita:

 

obj.innerHTML = XMLHttpRequestObject.responseText;

 

occorre effettuare la chiamata al server: tutto ciò che abbiamo fatto sinora è stato prepararla. La chiamata viene effettuata tramite una semplice istruzione:

 

XMLHttpRequestObject.send(null);

 

Perché viene passato un valore null? Perché il passaggio di eventuali parametri è previsto dal metodo POST, ma non dal metodo GET, e quindi va inviato un argomento vuoto.

Lo stesso risultato (ottenimento di una stringa di testo "Welcome to Ajax!" dal server può essere ottenuto chiamando un file php anziché un file txt. La funzione getData() sarà allora richiamata con la seguente istruzione, inserita nel tag <button>:

 

onclick = "getData('data.php', 'targetParagraph')"

 

Ovviamente dovrà esistere un file data.php sul server, che invii la stringa con la tipica istruzione "echo" di php. Ecco il contenuto del file data.php:

 

<?php

 echo "Welcome to Ajax!";

?>

 

 

 

Inviare dati al server tramite i metodi GET e POST e gestirli con una routine php

back to Index

 

 

Il metodo "GET" che abbiamo visto sopra consente, utilizzando un file php, di inviare, anziché ricevere dati al server. Per far questo è sufficiente far seguire il nome del file php con cui si vuole comunicare da un punto interrogativo seguito dal nome (arbitrario) dei parametri e dal loro valore:

Nel file AjaxExample2.htm abbiamo posto lo stesso codice di AjaxExample1.htm, tranne che per l'istruzione che contiene il file da chiamare (qui sotto evidenziata in colore):

 

<script language = "javascript">

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData(dataSource, divID)

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "data2.php?Nome=Pietro&Cognome=Gambadilegno");

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     document.getElementById(divID).innerHTML = XMLHttpRequestObject.responseText;

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

 

L'istruzione:

 

XMLHttpRequestObject.open("GET", "data.php?Nome=Pietro&Cognome=Gambadilegno");

 

contiene il parametro "Nome=Pietro" e il parametro "Cognome=Gambadilegno". I nomi dei parametri possono essere completamente arbitrari. Essi possono essere letti dal file data2.php con la seguente istruzione:

 

$Nome = $_GET["Nome"];

$Cognome = $_GET["Cognome"];

 

Per essere sicuri di aver acquisito il contenuto come stringa si può usare la variante:

 

$Nome = (string)$_GET["Nome"];

$Cognome = (string)$_GET["Cognome"];

 

Poi il nome e il cognome sono inviate indietro al computer client che ha effettuato la chiamata tramite l'istruzione:

 

echo $Nome." ".$Cognome;

 

L'intero codice del file data2.php è quindi:

 

<?php

 $Nome = $_GET["Nome"];

 $Cognome = $_GET["Cognome"];

 echo $Nome." ".$Cognome;

?>

 

Cliccando sul bottone, apparirà nel paragrafo MyParagraph il testo: "Il nome inviato al server è: Pietro Gambadilegno".

Per inviare questi dati, invece che il metodo GET si può usare il metodo POST. Si può osservare in azione tale metodo aprendo il file AjaxExample3.htm. Il codice ajax per collegarsi al server allora sarà il seguente (le modifiche sono evidenziate in colore):

 

<script language = "javascript">

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData()

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("POST", "data3.php");

   XMLHttpRequestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     document.getElementById("targetParagraph").innerHTML = "Il nome inviato al server è: "+XMLHttpRequestObject.responseText;

    }

   }

   XMLHttpRequestObject.send("Nome=Pietro&Cognome=Gambadilegno");

  }

 }

</script>

 

Come si vede, non viene più inviata una stringa nulla con l'istruzione XMLHttpRequestObject.send, ma una stringa contenente i parametri che col metodo GET venivano passati con l'URL del documento a cui collegarsi:

 

XMLHttpRequestObject.send("Nome=Pietro&Cognome=Gambadilegno");

 

Il codice del file data3.php sarà il seguente:

 

<?php

 $Nome=$_POST["Nome"];

 $Cognome=$_POST["Cognome"];

 echo $Nome." ".$Cognome;

?>

 

 

 

Acquisire un documento XML dal server e metterlo a disposizione di javascript

back to Index

 

 

Vediamo ora come si può utilizzare il codice ajax per il collegamento asincrono in modo da ottenere dal server non una stringa di testo, ma un documento XML. Proveremo a caricare e manipolare il file colors.xml, che ha il seguente contenuto:

 

<?xml version="1.0">

<colors>

<color>red<color>

<color>green</color>

<color>blue</color>

</colors>

 

Aprite il documento XMLDisplay2.htm ed osservatene il codice:

 

<html>

<head>

 

<script language = "javascript">

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData()

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "colors.xml?timestamp=" + new Date().getTime());

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     var xmlDocument=XMLHttpRequestObject.responseXML;

     var colors = xmlDocument.getElementsByTagName("color");

     document.getElementById("targetParagraph").innerHTML = "Il secondo colore è: " + colors[1].firstChild.nodeValue;

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

</script>

</head>

<body>

 

  </br>

  <p style="text-align:center;font-size:120%;font-weight:bold;">

   Un esempio di acquisizione di dati da un documento XML in modo asincrono da parte del browser tramite ajax:</br>

   La chiamata al file <span style="font-family:Courier New;font-size:90%">colors.xml</span> restituisce il documento <span style="font-family:Courier New;font-size:90%">xmlDoc</span>.</br>

   Il codice javascript di questa pagina legge i colori contenuti nei tag <span style="font-family:Courier New;font-size:90%">&#60;color&#62;</span>.</br>

   I nomi dei colori vengono poi visualizzati nel box, senza che il resto della pagina subisca il <i>refresh</i>.  

  </p>

 

  </br></br>

 

  <form style="text-align:center;">

    <input type = "button" value = "Acquisisci il messaggio" onclick = "getData();">

  </form>

 

  </br></br>

 

  <div align="center">

    <p id="targetParagraph" style="font-size:110%;color:red;border:1px solid black;height:40px;width:400px;margin:auto;padding-top:20px;padding-bottom:0px;">Il messaggio acquisito apparirà qui</p>

  </div>

 

</body>

</html>

 

Il codice evidenziato in colore contiene le istruzioni per acquisire e leggere il documento XML:

 

XMLHttpRequestObject.open("GET", "colors.xml?timestamp=" + new Date().getTime());

 

... ... ...

 

var xmlDocument=XMLHttpRequestObject.responseXML;

var colors = xmlDocument.getElementsByTagName("color");

document.getElementById("targetParagraph").innerHTML = "Il secondo colore è: " + colors[1].firstChild.nodeValue;

 

La prima riga configura l'oggetto XMLHttpRequestObject per una chiamata ajax, che poi viene effettuata con:

 

XMLHttpRequestObject.send(null);

 

Seguono poi delle righe che abbiamo omesso per controllare se il download dei dati sia avvenuto con successo, e poi la lettura dei dati inviati in formato XML e il loro salvataggio nella variabile xmlDocument:

 

var xmlDocument=XMLHttpRequestObject.responseXML;

 

Successivamente viene creato un array che contiene tutti i nodi <color> del documento XML:

 

var colors = xmlDocument.getElementsByTagName("color");

 

Infine, viene letto il valore del secondo nodo (dato che la numerazione degli array sovente inizia da "0", il secondo nodo avrà il numero "1"):

 

document.getElementById("targetParagraph").innerHTML = "Il secondo colore è: " + colors[1].firstChild.nodeValue;

 

Questo valore viene poi mostrato nel box "targetParagraph":

 

document.getElementById("targetParagraph").innerHTML = "Il secondo colore è: " + colors[1].firstChild.nodeValue;

 

 

 

Acquisire codice javascript dal server ed eseguirlo immediatamente tramite la funzione eval()

back to Index

 

 

Allo stesso modo in cui ajax può effettuare il download di testo e XML, può scaricare dal server codice javascript ed eseguirlo immediatamente. Aprite il file AjaxExample4.htm ed osservatene il codice:

 

<html>

<head>

<script language = "javascript">

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData()

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "data4.php");

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     eval(XMLHttpRequestObject.responseText);

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

 

 function show()

 {

  document.getElementById("targetParagraph").innerHTML="La funzione show() è stata attivata";

 }

 

</script>

</head>

<body>

 

  </br>

  <p style="text-align:center;font-size:120%;font-weight:bold;">

   Un esempio di acquisizione di dati in modo asincrono da parte del browser tramite ajax:</br>

   La chiamata al file <span style="font-family:Courier New;font-size:90%">data4.php</span> acquisisce il codice javascript della funzione <span style="font-family:Courier New;font-size:90%">show()</span> e lo esegue.</br>

   La funzione <span style="font-family:Courier New;font-size:90%">show()</span> fa apparire una stringa nel box.

  </p>

 

  </br></br>

 

  <form style="text-align:center;">

    <input type = "button" value = "Acquisisci il messaggio" onclick = "getData();">

  </form>

 

  </br></br>

 

  <div align="center">

    <p id="targetParagraph" style="font-size:110%;color:red;border:1px solid black;height:40px;width:400px;margin:auto;padding-top:20px;padding-bottom:0px;">Il messaggio acquisito apparirà qui</p>

  </div>

 

</body>

</html>

 

La prima linea di codice evidenziata in colore acquisisce l'echo del file data4.php, che consiste di una sola riga di codice javascript:

 

<?php

 echo 'show()';

?>

 

la stringa 'show()' viene eseguita come codice javascript dalla funzione eval(), e richiama la funzione definita nelle righe successive evidenziate in colore: questa funzione farà apparire un testo nel box della pagina.

 

 

 

Creare un oggetto javascript che incorpori una pagina html esterna e manipolarla

back to Index

 

 

E' possibile incorporare un documento html esterno in un oggetto javascript da poter trattare con una interfaccia DOM allo stesso modo dell'oggetto document che rappresenta la pagina corrente?

In alternativa, è possibile acquisirlo come pagina XML e leggerlo secondo la sintassi javascript per i files XML?

Quando una stringa è passata come parametro alla funzione $(…), jQuery controlla se abbia dei tag html; se non li ha, la stringa è interpretata come selettore; se li ha, viene creato un nuovo DOM element, sul quale possono essere effettuate tutte le operazioni jQuery.

 

Primo sistema: utilizzare l'istruzione .load di jQuery

Con jQuery disponiamo dell'istruzione:

 

$("#targetParagraph").load("MyPage2.htm #MyFirstParagraph");

 

che consente di caricare un elemento di una pagina web esterna (in questo caso "MyPage2.htm") direttamente in un elemento della pagina corrente (tipicamente un <div> o un <p> o un <td>). Mediante una stringa come "#MyFirstParagraph" si può selezionare uno specifico elemento tramite il suo id. Si ricordi solo di distanziare di uno spazio l'id dal nome del documento. Questa istruzione può caricare files di tipo diverso da html: files di testo o xml.

 

Secondo sistema: utilizzare una routine php che scarichi la pagina e la invii tramite ajax al computer client (sconsigliato)

Esistono delle istruzioni php che possono inviare un documento tramite la funzione echo:

 

var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest)

 {

  XMLHttpRequestObject = new XMLHttpRequest();

 }

 else if (window.ActiveXObject)

 {

  XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData()

 {

  if(XMLHttpRequestObject)

  {

   XMLHttpRequestObject.open("GET", "data5.php");

   XMLHttpRequestObject.responseType = "document";

   XMLHttpRequestObject.onreadystatechange = function()

   {

    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

    {

     alert(XMLHttpRequestObject.responseXML.getElementsByTagName("body")[0].nodeName);

    }

   }

   XMLHttpRequestObject.send(null);

  }

 }

 

Questa routine ajax richiama il file data5.php, che fa il dowload di un file da un server qualsiasi della rete (in questo caso dal server learningsources.altervista.org):

 

<?php

  $filehandle = fopen("www.learningsources.altervista.org/MyPage2.htm", "r");

  while (!feof($filehandle))

  {

   $download = fgets($filehandle);

   echo $download;

  }

  fclose($filehandle);

?>

 

Il codice ajax genera un alert che reca scritto "body" (che è il nome dell'elemento selezionato). L'utilizzo di php serve, in alternativa al caricamento diretto, a impedire che il processo di download sia interrotto da una richiesta di autorizzazione da parte del browser, che viene spesso visualizzata se il server dal quale si importa il file è diverso dal server a cui è collegato il browser. Ma il codice impiega circa trenta secondi per ultimare il caricamento e visualizzare l'informazione sul documento, pertanto è di scarsa utilità.

Stesso rallentamento inaccettabile utilizzando in alternativa una routine jQuery:

 

function getData()

{

 $.ajax

 ({

  url:"data5.php",

  dataType:"html",

  success:function(htmlDocument)

  {

   alert(XMLHttpRequestObject.responseXML.getElementsByTagName("body")[0].nodeName);

  }

 });

}

 

Terzo sistema: utilizzare il metodo document.implementation.createHTMLDocument

Esiste un metodo di recente introduzione per acquisire una pagina html esterna come oggetto document di javascript, che permette di utilizzare tutti i metodi e le proprietà di un modello DOM. Esso è supportato da Internet Explorer versione 9 e successive, da Chrome, Opera, Safari tra gli altri browser. Ecco la sintassi per creare tramite una routine ajax un simile documento e leggerne un tag <div> (con jQuery le istruzioni possono essere significativamente accorciate):

 

var XMLHttpRequestObject = false;

if (window.XMLHttpRequest)

{

 XMLHttpRequestObject = new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

 XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

}

 

function getData()

{

 if(XMLHttpRequestObject)

 {

  XMLHttpRequestObject.open("GET", "MyPage2.htm");

  XMLHttpRequestObject.onreadystatechange = function()

  {

   if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

   {

    var doc = document.implementation.createHTMLDocument("MyDocument");

    doc.documentElement.innerHTML = XMLHttpRequestObject.responseText;   

    alert(doc.getElementById("MyFirstParagraph").innerHTML);

   }

  }

  XMLHttpRequestObject.send(null);

 }

}

 

Il documento MyPage2.htm cui fa riferimento la routine (vedi istruzioni evidenziate in colore) ha il seguente contenuto:

 

<html>

<head>

</head>

<body>

 <p id="MyFirstParagraph">Questo e' il primo paragrafo</p>

 <p id="MySecondParagraph">Questo e' il secondo paragrafo</p>

</body>

</html>

 

Nell'alert box comparirà la stringa "Questo è il primo paragrafo". Anche gli altri metodi DOM javascript sono applicabili a questo oggetto, come ad esempio l'istruzione:

 

alert(doc.getElementById("MyFirstParagraph").attributes.id.value);

 

oppure l'istruzione:

 

alert(doc.getElementsByTagName("p")[0].innerHTML);

 

Quarto sistema: caricare la pagina in un tag <iframe> e leggerla (non funziona)

Ormai tutti i browser supportano il tag <iframe>, ottimizzato per il caricamento di elementi da altre pagine web. La sintassi per utilizzarlo è molto semplice:

 

<iframe src="http://www.w3schools.com"></iframe>

 

In questo caso si è caricata nella finestra la HomePage del consorzio w3schools. Una serie di attributi opzionali consente di settare la posizione, la larghezza della finestra, ecc. Per i nostri scopi l'iframe dovrebbe essere nascosto. Ma in realtà questa soluzione non funziona, perché quando si va a far eseguire l'istruzione:

 

alert(document.getElementById("MyIframe").childNodes.length);

 

Si ottiene il messaggio "0": cioè non ci sono nodi nel contenuto di "MyIframe".

 

ulteriore documentazione consultabile:

https://developer.mozilla.org/en-US/Add-ons/Code_snippets/HTML_to_DOM : contiene una descrizione del metodo document.implementation.createHTMLDocument, nel paragrafo "Parsing Complete HTML to DOM"

 

 

 

Come ottenere l'esatto indirizzo di una pagina internet che si vuole utilizzare con javascript

back to Index

 

 

Per poter utilizzare elementi di una pagina internet con javascript (vedi l'articolo sui vari modi di farlo) occorre disporre dell'indirizzo completo della pagina web. L'indirizzo andrebbe sempre digitato preceduto da "http://www.", per evitare malfunzionamenti di routines javascript o jQuery, e non semplicemente preceduto dal solo "www." (ad esempio questo indirizzamento non funziona con la funzione .load() di jQuery). Indirizzi come: "www.usatoday.com" o "www.flowersgallery.com" sono solo indirizzi di directory all'interno delle quali si trova il file-indice che viene inviato al browser, non di rado annidato in sottodirectory.

I server web sono configurati in modo da inviare una pagina di default ogni volta che un browser richiede un nome di directory. Per esempio, se il vostro link è "www.example.com/about/", un tipico server web cercherà in quella directory un file chiamato "index.html". Normalmente, una volta caricato questo file, esso non sarà mostrato nella barra degli indirizzi, che continuerà a mostrare la stringa sopra indicata.

Purtroppo, normalmente i server web disabilitano il listing della directory, che quindi non può essere ottenuto con nessun tipo di richiesta ajax o di altro tipo. In questi casi, si può solo tirare ad indovinare, provando i nomi più comuni, come "index.htm", "index.html", "index.php", "index.asp", ma se questo non funziona, non c'è modo di ottenere l'esatto indirizzo della pagina web.

Un modo di ottenerlo può essere l'utilizzo di GNU Wget, un programma open source che consente il download di files dai server usando HTTP, HTTPS, FTP, e che può essere usato per ottenere il listato della directory. Caratteristiche simili ha il programma cURL.

 

 

 

Una pagina per sperimentare semplice codice javascript, jQuery, ajax, php

back to Index

 

 

Aprite la pagina  Experiments_1.htm , provate a cliccare sui vari elementi e visualizzatene il codice con l'opzione "visualizza sorgente pagina" del tasto destro del mouse (per Explorer l'opzione è "HTML").

 

 

 

Alcune cose che con ajax non si possono fare, anche se apparentemente sembrerebbero semplici

back to Index

 

 

Per quanto questo possa lasciare increduli, è praticamente impossibile esportare i valori che si ottengono entro una routine che utilizza l'oggetto XMLHttpRequest, del tipo:

 

<script language = "javascript">

 

 var XMLHttpRequestObject = false;

 if (window.XMLHttpRequest) {

   XMLHttpRequestObject = new XMLHttpRequest();

 } else if (window.ActiveXObject) {

   XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

 }

 

 function getData()

 {

   if(XMLHttpRequestObject) {

     XMLHttpRequestObject.open("GET", "MiaPagina.php");

      XMLHttpRequestObject.onreadystatechange = function()

     {

       if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) {

           document.Message= XMLHttpRequestObject.responseText;

       }

     }

      XMLHttpRequestObject.send(null);

   }

 }

 

</script>

 

La funzione function getData() si collega al documento MiaPagina.php presente sul server e riceve in risposta la stringa XMLHttpRequestObject.responseText, che provvede a memorizzare nella variabile globale document.Message.

Ma questo codice non funziona, nel senso che nessuna routine javascript esterna alla funzione getData() sarà in grado di leggere e utilizzare il contenuto della variabile document.Message.

Il contenuto è stato acquisito con successo (per verificarlo è sufficiente scrivere, entro la routine getData(), l'istruzione alert(document.Message)); ma non è visibile all'esterno.

In altre parole: tutto il codice che fa riferimento al contenuto di document.Message deve essere scritto entro la routine getData().

Provare per credere. Impiegate tutti i trucchi che vi vengono in mente (memorizzazione entro un tag, richiamo di una funzione esterna a cui passare il valore e che lo scrive in una qualche parte, ecc.), niente funzionerà.

E questo è vero sia per javascript sia per una libreria sofisticata come jQuery

 

 

 

Cos'è un documento XML e come lo si può gestire

back to Index

 

 

Un documento XML è simile ad un documento HTML, nel senso che entrambi sono strutturati mediante tag, meglio detti nel caso di XML nodi o elementi:

 

<?xml version="1.0">

 <friends>

  <friend>

   <FirstName>Cary</FirstName>

   <LastName>Grant</LastName>

  </friend>

  <friend>

   <FirstName>Myrna</FirstName>

   <LastName>Loy</LastName>

  </friend>

  <friend>

   <FirstName>James</FirstName>

   <LastName>Stewart</LastName>

  </friend>

</friends>

 

A differenza di un documento HTML, in cui il tipo di elementi o tag è rigidamente predefinito, in un documento XML si può attribuire ad un tag un nome qualsiasi, come si vede sopra.

Tutti i documenti XML iniziano con una dichiarazione del tipo:

 

<?xml version="1.0">

 

E' necessario indicare la versione. Una versione comunemente usata è "1.0", ma si può indicare anche "1.1". Gli altri argomenti che possono essere inclusi sono standalone ed encoding, come ad esempio:

 

<?xml version="1.0" standalone="yes" encoding="UTF-8">

 

Standalone = "yes" indica che indica che il documento non include altri documenti XML.

Encoding = "UTF-8" stabilisce che si intende utilizzare il set di caratteri UTF-8, che è quello utilizzato da WordPad e altri standard editor di testo.

I nomi dei tag non possono iniziare con numeri, non possono contenere spazi o alcuni caratteri non consentiti come virgolette.

Tutti i documenti XML necessitano di un document element, cioè un singolo nodo o elemento che contiene tutti gli altri nodi o elementi del documento. Nell'esempio sottostante il document element è il nodo <colors> del file colors.xml:

 

<?xml version="1.0">

<colors>

<color>red<color>

<color>green</color>

<color>blue</color>

</colors>

 

Ogni altro elemento deve essere contenuto nel document element.

Possono esistere, come in HTML, empty elements, cioè elementi costituiti da un solo tag, che quindi non racchiudono alcun contenuto (il tag <img> in HTML è uno di questi). In XML un empty element deve terminare sempre con lo slash:

 

<evening/>

 

Questi elementi sono un'alternativa ad un nodo contenente l'informazione:

 

<party>

<evening/>

</party>

 

equivale a:

 

<party>

<time>evening</time>

</party>

 

Gli elementi XML possono anche includere attributi (che sono anch'essi considerati nodi):

 

<party type="winter">

 

In XML ad un attributo va sempre dato un valore.

Entro un nodo XML si può inserire del testo:

 

<PartyTitle>Snow Day</PartyTitle>

 

I nodi possono essere di vario tipo, e la proprietà nodeType restituisce un numero corrispondente:

 

Tipo di nodo

nodeType

Element node

1

Attribute node

2

Text Node

3

CDATA (XML character data) section node

4

XML entity reference node

5

XML entity node

6

XML processing instruction node

7

XML comment node

8

XML document node

9

XML DTD node

10

XML document fragment node

11

XML notation node

12

 

Un file XML può essere caricato in memoria sia dall'hard-disk del computer client che dall'hard-disk del server.

Per caricarlo dal server utilizziamo Ajax (il codice sarà commentato in seguito):

 

var XMLHttpRequestObject = false;

if (window.XMLHttpRequest)

{

 XMLHttpRequestObject = new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

 XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

}

if(XMLHttpRequestObject)

{

 XMLHttpRequestObject.open("GET", "colors.xml", true);

 XMLHttpRequestObject.onreadystatechange = function()

 {

  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  {

   var sourceDocument = XMLHttpRequestObject.responseXML;

   var xmlDocument = sourceDocument.documentElement;

   alert("Il nome del nodo principale è " + xmlDocument.nodeName);

   alert("Il nodo principale contiene " + xmlDocument.childNodes.length);

  }

 }

 XMLHttpRequestObject.send(null);

}

 

Il codice eseguito dopo il caricamento del documento fa apparire un box di dialogo con la stringa "colors", che è il nome del nodo documentElement, e successivamente un altro box con la stringa "3", che è il numero dei tag <color> contenuti nel documentElement.

Per caricare invece un documento presente sull'hard-disk del computer client si usa l'istruzione:

 

xmlSource=loadXMLDoc("colors.xml");

 

Supponiamo di avere un documento XML come il seguente:

 

<?xml version="1.0"?>

 <parties>

  <party type="winter">

   <party_title>Snow Day</party_title>

   <party_number>63</party_number>

   <subject>No school today!</subject>

   <date>2/2/2009</date>

   <people>

    <person attendence="present">

     <first_name>Ralph</first_name>

     <last_name>Kramden</last_name>

    </person>

    <person attendance="absent">

      <first_name>Alice</first_name>

      <last_name>Kramden</last_name>

    </person>

    <person attendance="present">

     <first_name>Ed</first_name>

     <last_name>Norton</last_name>

    </person>

   </people>

  </party>

</parties>

 

Supponiamo di aver già acquisito il document element del file party.xml mediante le istruzioni:

 

xmlSource=loadXMLDoc("party.xml");

xmlDocument = xmlSource.documentElement;

 

Vediamo ora come fare per estrarre il cognome del terzo ospite del party (Ed Norton) dal documento party.xml. Per far questo dobbiamo conoscere gli oggetti che javacript mette a disposizione per acquisire i nodi:

 

Oggetto javascript

Descrizione

element.childNodes

Array che contiene tutti i nodi di livello immediatamente inferiore a quello del nodo element, ed inclusi in esso

(nel caso dell’elemento document element i childnodes sono costituiti dal solo nodo <party>, mentre nel caso dell’elemento <people> i childnodes sono i nodi <person>)

element.firstChild

Il primo dei childnodes del nodo element, secondo la disposizioone che hanno nel documento.

(nel caso dell’elemento <people> il firstChld è il nodo <person> di Ralph Kramer)

element.lastChild

L’ultimo dei childnodes del nodo element, secondo la disposizioone che hanno nel documento.

(nel caso dell’elemento <people> il lastChld è il nodo <person> di Ed Norton)

element.nextSibling

Il successivo nodo di pari livello rispettto al nodo element

(nel caso dell’elemento <date> il nextSibling è il nodo <people>)

element.previousSibling

Il nodo precedente tra quelli di pari grado rispetto al nodo element

(nel caso dell’elemento <people> il previousSibling è il nodo <date>)

 

Con queste premesse, per ottenere la stringa “Norton” occorre utilizzare l’espressione:

 

xmlDocument.documentElement.firstChild.lastChild.lastChild.lastChild.firstChild.nodeValue

 

infatti si hanno le seguenti corrispondenze:

 

xmlDocument.documentElement.firstChild

nodo <party>

xmlDocument.documentElement.firstChild.lastsChild

nodo <people>

xmlDocument.documentElement.firstChild.lastChild.lastChild

nodo <person> di Ed Norton

xmlDocument.documentElement.firstChild.lastChild.lastChild.lastChild

nodo <last_name> di Ed Norton

xmlDocument.documentElement.firstChild.lastChild.lastChild.lastChild.firstChild

nodo di testo costituito dalla stringa “Norton”

 

La proprietà nodeValue consente di acquisire il contenuto dell’oggetto, che non può essere manipolato come dato o mostrato come tale nella pagina web (se si provasse a mettere l’espressione senza .nodeValue in un alert box il valore sarebbe “undefined”, il tipico risultato che si ottienne trattando un oggetto come un dato),

Equivalentemente, utilizzando l’oggetto nextSibling si può ottenere la stringa “Norton” con l’espressione:

 

xmlDocument.documentElement.firstChild.lastChild.firstChild.nextSibling.nextSibling.lastChild.firstChild.nodeValue

 

Proviamo ora un'altra via per acquisire la stringa "Norton", utilizzando l'array creato mediante getElementsByTagName:

 

var LastNames = xmlDocument.getElementsByTagName("last_name");

var EdNortonLastName = LastNames[2].firstChild.nodeValue;

 

(si tenga presente che la numerazione dell'array inizia con "0" e non con "1")

Cerchiamo ora di acquisire gli attributi di un nodo, ad esempio l'attributo "attendance" di Ralph Kramden:

 

var RalphKramdenAttendance = xmlDocument.getElementsByTagName("person")[0].attributes.getNamedItem("attendance");

 

Un utile trucco per individuare uno specifico nodo che ci interessa è quello di creare un loop che scorra tutti i nodi e verifichi una condizione che ci consenta di identificare il nodo che ci interessa. Supponiamo di voler trovare lo stesso dato dell'esempio precedente, cioè la presenza di Ralph Kramden. Carichiamo party.xml in memoria ed acquisiamo il document element con le istruzioni:

 

xmlSource=loadXMLDoc("party.xml");

xmlDocument = xmlSource.documentElement;

 

Successivamente scorriamo tutti i nodi <person> del document element, alla ricerca del nodo di Ed Norton:

 

Guests = xmlDocument.getElementsByTagName("person");

var LoopIndex;

for(LoopIndex=0;LoopIndex<Guests.length;LoopIndex++)

{

 if (Guests[LoopIndex].LastChild.nodeValue = "Kramden")

 {

  RalphKramdenAttendance = Guests[LoopIndex].attributes.getNamedItem("attendance");

  alert(RalphKramdenAttendance);

 }

}

 

 

Ecco il riepilogo di alcune istruzioni con cui è possibile manipolare il documento

 

xmlDocument.documentElement.Childnodes

xmlDocument.documentElement.Childnodes.length

xmlDocument.documentElement.Child

xmlDocument.documentElement.getElementsByTagName("colore")[0]

xmlDocument.documentElement.firstChild.nodeValue

 

 

 

Leggere un documento XML posto sul server e farne apparire il contenuto nella pagina web

back to Index

 

 

Consideriamo la seguente pagina XMLDisplay1.htm :

 

<html>

<head>

<style type ="text/css">

.AjaxBox {

 margin-left: auto;

 margin-right: auto;

 width:40%;

 height:auto;

 text-align:center;

 border:1px solid black;

 padding-top:10px;

 padding-bottom:10px;

 background-color:AliceBlue;

 text-align:center;

 vertical-align : center;

 position : absolute;

 left : 30%;

 top : 100px;

 }

</style>

 

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>

 

<script type="text/javascript">

 

function DisplayXML()

{

 $.get("XMLSend.php",function(xmldoc)

 {

  var ArrayPoesie=xmldoc.getElementsByTagName("Testo");

  var LoopIndex;

  document.getElementById("Poesie").innerHTML="";

  for(LoopIndex = 0; LoopIndex<xmldoc.documentElement.childNodes.length; LoopIndex++)

  {

document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+ArrayPoesie[LoopIndex].firstChild.nodeValue+"</p>";

  }

 },"xml");

}

 

</script>

 

</head>

<body>

 

<div id="Poesie" class="AjaxBox">

<p><a id="MyAnchor" href="#" onclick="DisplayXML();">Clicca qui per acquisire e leggere un file XML tramite ajax</a></p>

</div>

 

</body>

 

</html>

 

Il blocco di codice:

 

<div id="Poesie" class="AjaxBox">

<p><a id="MyAnchor" href="#" onclick="DisplayXML();">Clicca qui per acquisire e leggere un file XML tramite ajax</a></p>

</div>

 

crea un box nella pagina web dove comparirà il testo delle poesie.

Il blocco di codice:

 

function DisplayXML()

{

 $.get("XMLSend.php",function(xmldoc)

 {

  var ArrayPoesie=xmldoc.getElementsByTagName("Testo");

  var LoopIndex;

  document.getElementById("Poesie").innerHTML="";

  for(LoopIndex = 0; LoopIndex<xmldoc.documentElement.childNodes.length; LoopIndex++)

  {

document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+ArrayPoesie[LoopIndex].firstChild.nodeValue+"</p>";

  }

 },"xml");

}

 

definisce la funzione DisplayXML() che si attiva quando si clicca sul testo posto nel box, e vi inserisce il testo delle poesie.

Mediante l'istruzione:

 

$.get("XMLSend.php",function(xmldoc){...},"xml");

 

(dove, al posto dei puntini ci sono le istruzioni che commenteremo) la funzione DisplayXML() apre in modo ajax (asincrono) il file XMLSend.php, che legge il file Haiku.xml e lo invia come documento XML (xmldoc):

 

<?php

 $Haiku = simplexml_load_file('Haiku.xml');

 $xmlDocument ="<?xml version='1.0'?><dataroot>";

 foreach($Haiku->children() as $item)

 {

  $xmlDocument=$xmlDocument."<Haiku>";

  $xmlDocument=$xmlDocument."<Autore>".$item->Autore."</Autore>";

  $xmlDocument=$xmlDocument."<Testo>".$item->Testo."</Testo>";

  $xmlDocument=$xmlDocument."</Haiku>";

 }

 $xmlDocument=$xmlDocument."</dataroot>";

 echo $xmlDocument;

?>

 

Il file Haiku.xml (e il documento xmldoc) si presenta così:

 

<?xml version="1.0" encoding="UTF-8"?>

<dataroot>

 

<Haiku>

<Indice>1</Indice>

<Autore>Ito Shintoku</Autore>

<Epoca>1634-1698</Epoca>

<Paese>Giappone</Paese>

<Soggetto>pioggia</Soggetto>

<Testo>pioggia: attraversa il mio cancello un mazzo di iris</Testo>

</Haiku>

 

...

 

<Haiku>

<Indice>7</Indice>

<Autore>Konishi Raizan</Autore>

<Epoca>1653-1716</Epoca>

<Paese>Giappone</Paese>

<Soggetto>campi di neve</Soggetto>

<Testo>nei campi di neve verdissimo il verde delle erbe nuove</Testo>

</Haiku>

 

...

 

<Haiku>

<Indice>10</Indice>

<Autore>Konishi Raizan</Autore>

<Epoca>1653-1716</Epoca>

<Paese>Giappone</Paese>

<Soggetto>alzo il capo</Soggetto>

<Testo>alzo il capo e vedo me coricato nel freddo</Testo>

</Haiku>

 

</dataroot>

 

Torniamo alla funzione richiamata con l'istruzione ajax:

 

$.get("XMLSend.php",function(xmldoc){...},"xml");

 

che ora ha a disposizione il documento xmldoc, ed analizziamone le istruzioni:

 

{

  var ArrayPoesie=xmldoc.getElementsByTagName("Testo");

  var LoopIndex;

  document.getElementById("Poesie").innerHTML="";

  for(LoopIndex = 0; LoopIndex<xmldoc.documentElement.childNodes.length; LoopIndex++)

  {

   document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+ArrayPoesie[LoopIndex].firstChild.nodeValue+"</p>";

  }

 

L'istruzione:

 

xmldoc.getElementByTagName("..")

consente di creare degli array che contengono ad esempio tutti i campi (nodi) <Soggetto>…</Soggetto>, o tutti i campi (nodi) <Autore>…</Autore> ecc. del documento XML (xmldoc).

Nel nostro caso abbiamo creato un array che contiene tutti i campi (nodi) <Testo>…</Testo>

 

var ArrayPoesie=xmldoc.getElementsByTagName("Testo");

 

Questo array è indicizzato in modo numerico a partire dal numero zero. Ad esempio l'espressione:

 

ArrayPoesie[0]

 

restituisce il nodo:

 

<Testo>pioggia: attraversa il mio cancello un mazzo di iris</Testo>

 

 che contiene la prima poesia.

La stringa contenuta nel nodo è rappresentata dall'espressione:

 

ArrayPoesie[0].firstChild.nodeValue

 

Il codice javascript effettua un ciclo che acquisisce una per una queste stringhe e le aggiunge al contenuto del tag "Poesie":

 

  for(LoopIndex = 0; LoopIndex<xmldoc.documentElement.childNodes.length; LoopIndex++)

  {

   document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+ArrayPoesie[LoopIndex].firstChild.nodeValue+"</p>";

  }

 

L'istruzione che aggiunge la nuova riga alle precedenti è precisamente:

 

document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+ArrayPoesie[LoopIndex].firstChild.nodeValue+"</p>";

 

Ecco ora una seconda variante della funzione DisplayXML, che, pur utilizzando la variabile xmldoc utilizza un altro tipo di istruzioni javascript:

 

function DisplayXML()

{

 $.get("XMLSend.php",function(xmldoc)

 {

  var Poesie = xmldoc.documentElement;

  var LoopIndex;

  document.getElementById("Poesie").innerHTML="";

  for(LoopIndex = 0; LoopIndex<Poesie.childNodes.length; LoopIndex++)

  {

   document.getElementById("Poesie").innerHTML=document.getElementById("Poesie").innerHTML+"<p align='center'>"+Poesie.childNodes[LoopIndex].lastChild.firstChild.nodeValue;+"</p>";

  }

 },"xml");

}

 

Anziché l'array

 

xmldoc.getElementsByTagName("Testo")

 

viene utilizzato l'oggetto

 

xmldoc.documentElement

 

i cui nodi rappresentano un tag <Haiku> … </Haiku>, all'interno del quale lastChild rappresenta il tag <Testo> … </Testo> il cui contenuto è rappresentato da lastChild.firstChild.nodeValue, perché il testo contenuto tra i tag rappresenta a sua volta un nodo (di testo).

 

 

 

Suggerimenti vari

back to Index

 

 

 

Ricordate che una pagina contenente codice php non eseguirà quel codice se il file avrà l'estensione ".htm" anziché quella ".php"

 

Per forzare l'editor di WordPad o di BloccoNote a salvare un file di testo con l'estensione che volete, dovete virgolettarne il nome, ad esempio: "MyScript.php"

 

Il codice php non verrà eseguito a meno che il file che lo contiene non sia stato caricato sul server php e richiamato da lì.

 

Ricordate che javascript usa due segni di uguaglianza per operare i confronti tra stringhe o numeri, mentre usa un solo segno solo per impostare il valore di una variabile: tenere presente questa importante distinzione vi eviterà tempo inutile a caccia del perché il vostro codice non funziona.

 

Non usate mai il bottone con type="submit" per triggerare una modifica del documento html operata tramite una funzione javascript: questo è impossibile, perché la pressione di questo tipo di bottone provoca immancabilmente un refresh della pagina che annulla qualsiasi modifica apportata con javascript. Utilizzate invece il bottone con type="button", e tutto filerà liscio.

 

Quando settate le dimensioni di un box state attenti a scrivere "px" senza spazi accanto alla misura:

 

width : 100px

 

e non:

 

width : 100 px

 

che non funzionerebbe!

 

Quando si scrivono le istruzioni per la lettura di un documento XML si tenga presente che purtroppo Firefox considera eventuali caratteri usati per l’indentazione dei tag come nodi autonomi. E’ consigliabile in tal caso l’uso di una routine che rilevi se il browser è Firefox e in caso affermativo proceda a rimuovere tutti gli spazi:

 

 var loopIndex;

 for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++)

 {

  var currentNode = xml.childNodes[loopIndex];

  if (currentNode.nodeType == 1)

  {

   removeWhitespace(currentNode);

  }

  if (((/^\s+$/.test(currentNode.nodeValue))) && currentNode.nodeType == 3))

  {

   xml.removeChild(xml.childNodes[loopIndex--]);

  }

 }

 

 

 

Argomenti vari

back to Index

 

 

 

Cos'è  un server Apache

Robin Nixon, Learning PHP, MySQL, JavaScript & CSS, O'Reilly

 

Brevi  cenni sugli elementi più importanti di una pagina web

<title></title> Contiene il titolo del documento web che è mostrato nella barra/linguetta del titolo nel browser

<body></body> Contiene tutti gli elementi che appaiono nella pagina. Gli elementi che non sono posti qui non sono visibili

<style></style> Controlla il modo di apparire e il comportamento dei vostri elementi web

<script></script> Qui viene inserito codice javascript o di altro linguaggio

<div></div> Molto usato come contenitore generico dove possono essere posti gli altri tipi di tag che compaiono in <body>

<p></p> Crea un paragrafo: prima del testo sarà inserito un ritorno a capo

</br> Inserisce una linea vuota

<button></button> Crea un bottone che può essere collegato in evento, in alternativa al codice: <input type="button">

<form></form> Crea una maschera per l'immissione di dati, che normalmente contiene elementi <input> come bottoni o caselle di testo

<input> Crea l'elemento di un form: caselle di spunta, caselle di testo, bottoni

<table></table> Crea una tabella

 

Caricare  una immagine in una pagina web

Il tag di una immagine ha la seguente struttura:

 

<img src="House.gif" height="30" width="30" alt="Immagine di una casa" />

 

Usare  files javascript esterni

Il comando per utilizzare il codice che abbiamo inserito in un file chiamato "MyScript.js", posto nella stessa directory della pagina web è il seguente:

 

<script language="javascript" src="MyScript.js">

 

Se il file "MyScript.js" non è nella stessa directory va indicato l'indirizzo completo, che può anche esserre un URL, come nel caso della libreria jQuery:

 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

 

Selezionare un elemento della pagina

Se si è dotato un tag di un id, come ad esempio:

 

<p id="MyParagraph">Questo e' il mio paragrafo</p>

 

in javascript si può semplicemente utilizzare l'id, per leggere/scrivere nell'elemento:

 

MyParagraph.innerHTML = "Questo e' sempre il mio paragrafo";

 

Utilizzare la sintassi XML per muoversi nell'oggetto document

Per muoversi nell'oggetto document, che incorpora gli elementi della pagina html in cui è scritto il codice javascript, è anche possibile utilizzare l'oggetto document.documentElement, che permette di accedere ai tag visti come nodi di un documento XML con la stessa sintassi utilizzata per tali documenti, come ad esempio:

 

alert(document.documentElement.childNodes.length);

 

alert(document.documentElement.childNodes[0].nodeName);

 

alert(document.documentElement.getElementsByTagName("p")[1].firstChild.nodeValue);

 

alert(document.documentElement.childNodes[2].firstChild.nextSibling.nextSibling.nextSibling.attributes.getNamedItem("id").value);

 

alert(document.getElementById("myDIV").childNodes.length);

 

Quando si scrive il codice per navigare in un documento html, i tag <script> costituiscono un tag di tipo 3 (text), e occorre fare attenzione se si sono richiamati dei files javascript esterni, che sono inclusi nel documento e che aggiungono altri nodi alla struttura della pagina, di cui occorre tenere conto. Uguale cautela occorre usare se nella pagina sono inseriti automaticamente dall'Host dei contatori, come ad es. con altervista.org, perché in tal caso si aggiungono altri nodi alla pagina.

 

Aprire nella pagina una finestra in cui è visualizzata un'altra pagina internet

Ormai tutti i browser supportano il tag <iframe>, ottimizzato per il caricamento di elementi da altre pagine web. La sintassi per utilizzarlo è molto semplice:

 

<iframe src="http://www.w3schools.com"></iframe>

 

In questo caso si è caricata nella finestra la HomePage del consorzio w3schools. L'effetto nella pagina web è il seguente:

 

 

Una serie di attributi opzionali consente di settare la posizione, la larghezza della finestra, ecc.

 

La  funzione jQuery $(document).ready(){…} è utile anche con semplice codice javascript

La funzione jQuery $(document).ready(){…} è utile anche con semplice codice javascript, perché consente ad istruzioni che fanno riferimento ad elementi che devono essere caricati, di funzionare. Consideriamo ad esempio il seguente codice:

 

<html>

<head>

<script language = "javascript">

alert(document.getElementById("MyIframe").nodeName);

</script>

</head>

<body>

<iframe id="MyIframe" style="position:absolute;left:30%;top:35%;" src="http://www.w3schools.com"></iframe>

</body>

</html>

 

Ma con la funzione $(document).ready(), esso funzioa e genera l'alert "IFRAME":

 

<html>

<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<script language = "javascript">

$(document).ready(function(){

alert(document.getElementById("MyIframe").nodeName);

});

</script>

</head>

<body>

<iframe id="MyIframe" style="position:absolute;left:30%;top:35%;" src="http://www.w3schools.com"></iframe>

</body>

</html>

 

La funzione setTimeout()

Consideriamo il seguente codice:

 

javascript

 

function DisplayData(Testo)

{

 var MyBox = document.getElementById("targetDiv");

 MyBox.style.color = "red";

 MyBox.innerHTML = Testo;

 setTimeout(attentionGetter, 500);

}

function attentionGetter()

{

 var target = document.getElementById("targetDiv");

 target.style.color = "black";

}

 

html

 

<form>

<input type = "button" value = "Cambia il testo" onclick = "DisplayData('Questo è il nuovo testo');">

</form>

 

<div id="targetDiv">

 <p>I nuovi dati appariranno qui</p>

</div>

 

Quando si preme il bottone, in "targetDiv" la stringa "I nuovi dati appariranno qui" viene sostituita dalla stringa "Questo è il nuovo testo", che per mezzo secondo apparirà colorato in rosso per poi tornare di colore nero. Questo è ottenuto con l'istruzione:

 

setTimeout(attentionGetter, 500);

 

Che lascia passare mezzo secondo (500 millisecondi) prima di chiamare la funzione attentionGetter(), che colora di nero la stringa inserita temporaneamente col colore rosso.

 

I caratteri speciali in javascript

Una istruzione come:

 

<input type = "button" value = "Cambia il testo" onclick = "DisplayData('QUESTO E' IL NUOVO TESTO');">

 

non funziona, perché compare il carattere " ' " entro la stringa che è l'argomento della funzione DisplayData().

 

Librerie javascript concorrenti rispetto a jQuery

AngularJS è una libreria sviluppata da un programmatore di Google, Miško Hevery, attualmente patrocinata da Google e distribuita come software gratuito open source. Da una recente ricerca risulta che 7000 siti web, su un milione testato, usano questa libreria, tra cui NBCWalgreensIntelSprint, ABC News. Non è di facile apprendimento, e per padroneggiarne appieno le funzionalità è necessaria una notevole esperienza di programmazione. Le statistiche delle ricerche in rete confermano questo dato: mostrano che il numero di ricerche riguardanti chiarimenti su Angular.js è nettamente superiore a quello delle ricerche che riguardano javascript, jQuery o altri linguaggi del web. Rispetto ad essa jQuery è più semplice e intuitiva. Per questo motivo non pochi programmatori pensano che, malgrado il supporto di Google, sia destinata ad essere abbandonata, come in passato è precisamente avvenuto con librerie molto valide ma poco intuitive.

Backbone.js è una libreria javascript conosciuta anche come CoffeeScript, creata dal programmatore Jeremy Ashkenas.

Prototype Javascript Framework è una libreria creata da Sam Stephenson nel 2005 e pensata come supporto di Ajax.

Moo Tools è una delle più popolari librerie javascript ed è distribuita open source con licenza del MIT.

YUI Library (Yahoo! User Interface Library) è stata creata nel 2005 da un team di sviluppatori Yahoo!, ma lo sviluppo attivo è cessato nel 2014, quando Yahoo! ha annunciato l'abbandono del supporto a causa della evoluzione degli standard javascript, del declinante interesse per larghe librerie javascript e per la proliferazione di soluzioni server-side.

Ember.js

Knockout

 

Concatenabilità di jQuery

jQuery consente di concatenare i comandi evitando di ripeterne ogni volta la parte iniziale. Ad esempio, si considerino i seguenti comandi javascript:

var links = $("a");

links.css( "color", "red" );

links.bind( "click", myFunctionPointer );

links.show( "1000" );

links.css( "width", "150px" );

Esso può essere sostituito da:

$("a").css({color:"red", width:"150px"}).bind("click", myFunctionPointer).show("1000");

Che ha la stessa leggibilità e si riduce ad una sola riga.

 

I  codici dei colori

Un colore, ad esempio di un bordo, può essere indicato, in un foglio di stile, in tre modi:

 

border-color : #000000;

border-color : rgb(0,0,0);

border-color : black;

 

Il terzo caso riguarda solo i colori principali, che hanno dei nomi individuali.

 

ulteriore documentazione consultabile:

http://www.w3schools.com/html/html_colors.asp : Tutorial sui colori

http://www.w3schools.com/html/html_colornames.asp : Elenco dei colori che possiedono dei nomi individuali.