Crea sito

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")

  {