16/01/2006 - Una mail mi ha fatto finalmente ricordare che dall'ottobre del 2004!!! ho pronta una versione dei menu a tendina che consentono anche di pilotare frames ed iframe.
Va on-line stamattina per tutte e tre le versioni del menu (questa, quella verticale e quella orizzontale).
La gestione dei frames è abbastanza semplice, e non richiede l'inserimento di un nuovo array: ho semplicemente modificato il modo di utilizzo dell'array "Targets", che finora pilotava solo nuove finestre, con un piccolo hack per indicare l'eventuale frame di destinazione ed i parametri per la pop-up.
La prima parte della stringa ("nome" o lettera+|) indica il tipo di destinazione:
- "win" sta per "nuova finestra": analogo al target='_blank' di un normale link A HREF
- "self" apre nello stesso frame in cui e' contenuto il menu, analogo al target="_self" di un normale link A HREF
- "top" apre il link sostitendo il frameset, analogo al target="_top" di un normale link A HREF
- "p|" sta per pop-up, seguono nella stessa stringa le consuete istruzioni per la formattazione, ad esempio "p|width=100,height=100,resizable=yes"
- "f|" sta per "in un frame", segue il nome del frame in cui aprire il link, ad esempio "f|nomeframe".
Se non viene riconosciuta la stringa di destinazione, il link viene aperto in modalita' "self", quindi sostituendo la pagina in cui e' contenuto il menu.
Forse e' un po' macchinoso, ma evita di dover gestire un altro array solo per poter specificare il nome di un eventuale frame. :-)
Nell'esempio che segue:
- il primo link vene aperto in un'altra finestra del browser;
- il secondo nello stesso frame dov'e' contenuto il menu;
- il terzo sostituisce il frameset
- il quarto nel frame "contenuti"
- il quinto in una pop-up di 300x400 pixel
targets[...]=new Array("win", "self", "top", "f|contenuti", "p|width=300,height=400")
10/04/2004 - Grazie ad una segnalazione in it.comp.lang.javascript e it.lavoro.professioni.webmaster, mi sono accorto ieri che lo script non funzionava con browser recenti nel caso si usasse una DTD diversa dall HTML4 per il documento.
Questo "semplicemente" perché nel 1999, quando è stato codato lo script non mi ero posto il problema :-))
Da oggi comunque i document.write() che scrivono i livelli nel documento producono codice valido secondo la DTD XHTML 1.0Strict dunque non dovrebbero piu' esserci problemi di compatibilità... almeno fino a quando una nuova DTD non ripresenterà gli stessi problemi.
Le pop-up di prova sono da oggi esse stesse documenti XHTML 1.0Strict.
07/04/2004 - Da oggi è possibila aprire i links anche in una popup.
Per farlo è sufficiente agire sull'array "targets" inserendo, al posto di "new" o "self", la stringa parametri che normalmente si scriverebbe in una window.open.
Non è necessaria nessun'altra modifica, la funzione che apre il link si accorgerà in automatico della presenza di parametri per una pop-up ed agirà di conseguenza. Nell'esempio on-line il link che va in pop-up è stato segnalato nel testo.
19/11/2003 - Sempre più spesso mi si chiede "come posso usare delle immagini al posto dei testi"?.
Sconsiglio sempre quest'operazione per un motivo molto semplice: con un menu di media complessità (come quello di esempio) il browser dovrebbe scaricare circa 20/30 immagini in più dal server per mostrare il menu, e ne conseguirebbe un notevole rallentamento per caricare la pagina.
Per chi volesse farlo comunque, la soluzione è in ogni caso molto semplice. Nell'array "voci" invece del nome del link mettere il tag <IMG ... > completo usando però, attenzione, l'apice singolo e non il doppio per i parametri, in quanto il doppio viene già usato nella struttura dell'array e comunque nello script.
Nella riga che segue vi ripropongo lo stesso array che trovate nell'esempio, ma per l'elemento [0] ho inserito, per i primi 3 elementi, immagini al posto delle stringhe; var voci=new Array();
voci[0]=new Array("<img src='javascript.gif'>","<img src='staffscripts.gif'>","<img src='userscripts.gif'>","<img src='flyscripts.gif'>","P.O.J.'>","Newsgroup icly");
voci[1]=new Array("Documenti","F.A.Q & Answers","Tutorials","Risorse e Downloads","Biblioteca","Links");
voci[2]=new Array("About us","Staff","Collaboratori","Contatti","Credits");
voci[3]=new Array("Varie","Servizi Gratuiti","Sondaggi","Hanno detto di noi","Banner","Advertising","Questo menu...");
Fatta questa modifica lo script scriverà nel link il tag IMG invece del testo ed il browser caricherà l'immagine.
Ovviamente non è possibile fare un rollover di immagini, non c'è la parte di script classica perché per semplicità sto evitando di farvi metter mano alla parte che lavora dello script (quella "da non modificare").
Un banale effetto di rollover lo potete ottenere lasciando trasparente lo sfondo delle immagini, in questo modo le funzioni che già fanno il rollover applicando un diverso colore di sfondo ai links dovrebbero continuare a farlo, e vedreste il colore di "over" applicato allo sfondo delle immagini. Non ho provato, se qualcuno mi fa sapere... fa un favore a tutti :-)
15/01/2003 - Chi ha scaricato lo script nell'ultimo mese potrà aver notato che non venivano visualizzati i mesaggi nella barra di stato. È stata solo una dimenticanza dall'ultimo aggiornamento (quello del 9/12/2002) per il quale avevo commentato le istruzioni relative per necessità di debug.
Non e' necessario riscaricare lo script e reinserire i valori degli array, se riscontrate questo problema nel vostro sito sarà sufficiente togliere il doppio slash davanti alle ultime due righe della funzione mroll()
09/12/2002 - Alcuni aggiornamenti a questo menu ed ai suoi derivati (Menu a tendine verticale e Menu Orizzontale); erano pronti da alcune settimane, ma non avevo avuto il tempo di mandarli on-line.
La modifica minore riguarda lo stile del tasto HOME e delle voci principali.
Nelle versioni on-line fino a ieri il tasto usciva in italico grazie a due tag <I>...</I> inseriti direttamente nei links scritti dai livelli, ora i tag sono stati eliminati ed è stato aggiunto lo stile "font-style:italic;" nelle due classi principali (menuNNb e menuIEb) rendendo di fatto più immediata e sicuramente non "pericolosa" la modifica dello stile.
Un'altra modifica spesso richiesta, è quella di rendere cliccabili anche le voci principali del menu, in modo da poter collegare una pagina principale della sezione, senza esser costretti a replicare la voce principale nella tendina.
Ovviamente se non si vuole rendere cliccabile la voce principale, è sufficiente inserire un cancelletto "#" al posto del nomefile nell'array links.
La modifica più importante, che ultimamente mi era stata più volte richiesta, riguarda la possibilità di aprire i links in una nuova finestra.
È stato aggiunto un ulteriore array targets in cui è possibile, al momento, dare due soli valori: "self" e "new", il primo valore fa funzionare i links nel modo "normale", cioè aprendo il link nella stessa finestra per il menu a tendine di questa scheda e di quello verticale e nel frame specificato (v. nota nella scheda) per quello orizzontale, inserendo invece il valore "new" il link viene aperto in una nuova finestra simulando il classico parametro TARGET="_new" dei normali link <A HREF ... >.
Come per gli altri array, anche questo conterrà lo stesso identico numero di voci dell'array links e tutte dovranno essere singolarmente specificate, considerando il valore "self" come valore di default che comunque andrà inserito come nell'esempio.
Di prossima implementazione la possibilità di aprire anche dei pop-up specificandone tutte le caratteristiche, e rendere così assolutamente indipendenti tutte le possibili pop-up volute; dovrebbe essere pronto per il prossimo fine settimana, il tempo di trovare una soluzione facile da eseguire, per voi, e da spiegare per me :-)
02/12/2002 - Domanda frequente: "Ho un sito a frames, ma i livelli del menu non si visualizzano sul frame sotto/a fianco, come posso fare?".
Un livello è un oggetto del documento che lo contiene, dunque non può scavalcare il "confine" del suo spazio. Non è possibile dunque obbligare i livelli a restare visibili anche su frame adiacenti a quello che contiene il menu.
Per risolvere questo problema esiste una versione "orizzontale" del menu che si sviluppa in una sola riga sotto alla riga principale, ovviamente con la limitazione dello spazio orizzontale a disposizione sarà possibile inserire un numero molto limitato di voci.
È possibile scaricare questa versione del menu dal link che segue: Menu Orizzontale
06/05/2002 - A causa di un mio errore nella correzione del bug su Mac, la pagina con il menu veniva cancellata dal browser quando il menu veniva utilizzato in un sito con frames. Le 3 versioni del menu sono ora corrette, comunque non è necessario rifare da capo tutto, basta modificare (alla riga 161) da navigator.platform.toLowerCase().indexOf("mac")!="mac")
in navigator.platform.toLowerCase().indexOf("mac")=="mac")
cioè cambiare il "punto esclamativo" in "uguale".
Mi scuso con tutti e ringrazio chi mi ha scritto per segnalarmi il problema.
09/04/2002 - Corretto un piccolo bug che rendeva instabile il funzionamento del menu con Exploer su Mac.
Non è necessario alcun intervento nella sezione personalizzabile del codice. (Grazie a Claudio Rebonato per la segnalazione
ed a Marco Catarsi e Marco Balestra per la verifica)
27/03/2002 - Tre aggiornamenti questa volta.
-----------------------------------------------------
Spesso mi è stato chiesto come eliminare il tasto Home. Nella versione precedente era sufficiente cancellare i due document.write() che scrivevano il relativo layer ed il "+50" nei document.write() successivi che scrivevano i livelli secondari e la formula per il calcolo della larghezza totale del menu.
Non era una cosa facile per chi non è ancora abbastanza esperto di JavaScript e si perde nel codice, abbastanza complesso, di questo menu.
Per questo nella versione che è on-line da oggi ho implementato da codice questa possibilità inserendo le 4 righe dalla 15 alla 18 e modificando opportunamente.
Sarà sufficiente ora impostare la variabile Home a false per non far comparire il link, senza dover più agire sulla parte non personalizzabile.
Le due variabili successive servono per impostare il link ed il testo associato e l'ultima per la larghezza del livello che, se è voluto, dovrà essere impostata per tentativi: ad esempio per scrivere "Homepage" invece di "Home" dovrà essere settata al valore 80.
-----------------------------------------------------
Se non si vuole che il menu sia centrato nella pagina, ma posizionato esattamente secondo il valore dato alla variabile topmargin, è sufficiente commentare la riga 57 inserendo due slash: // all'inizio.
-----------------------------------------------------
Infine: ho modificato le due funzioni del RollOver (mroll() e unmroll()) perché resti evidenziata anche la voce principale mentre il mouse si sposta fra quelle secondarie.
Se non si desidera quest'opzione è sufficiente commentare con // le righe 168, 169, 183 e 184.
04/03/2002- Grazie a Simone e Roberto, ora il menu funziona bene anche per Opera, almeno la versione 5.11.
18/01/2002 - Corretto il posizionamento del menu anche per Netscape6 (tnx a Lorenzo).
10/12/2001 - Corretto un bug nel menu, ora funziona bene (come ha funzionato per dei mesi nel sito! :-) anche per Explorer.
08/12/2001 - Il menu di questo script veniva usato fino a Novembre 2001 come menu principale del sito.
16/09/2001 - Quasi giornalmente ormai mi arrivano in e-mail queste due richieste: - Come posso far si che i link si aprano in un frame?
- Ho inserito il menu nel mio sito, ma quando ridimensiono il browser il menu si sposta mentre a voi non succedeva. come mai?
Per la prima domanda la risposta è semplice: alla riga 157 (ovviamente faccio riferimento allo script di esempio), invece di ...self.location.href=... scrivete ...top.frames.NOMEDELFRAME.location.href=..., dove al posto di "NOMEDELFRAME" ovviamente metterete il nome che avete assegnato al frame nel FRAMESET... e che nessuno mi venga a chiedere "dove lo trovo il nome del frame?" :-)))
Per al seconda invece, la risposta è "a noi non succedeva perché il contenuto delle pagine era accostato al margine sinistro del browser, quindi il posizionamento dei layers era assoluto". Se invece le vostre pagine sono centrate nella pagina, per spostare il menu in base alla dimensione della finestra o alla risoluzione dello schermo, è sufficiente inserire tre righe di codice.
Fra le righe 50 e 52 (in verde) inserite queste istruzioni (in rosso):
var nn=document.layers?true:false,conta=0,last=0;
MenuLength=50+largo*voci.length;
BrowserWidth=document.all?document.body.clientWidth:window.innerWidth;
leftmargin=parseInt((BrowserWidth-MenuLength)/2);
if (nn)
Ovviamente le stesse modifiche valgono anche per il menu in versione verticale.
Quanto detto sopra vale solo se avevate scaricato lo script prima del 16 settembre, negli archivi che sono on line a partire da quella data tutte queste modifiche sono già implementate.
BugFix! 29/06/2001 - Corretto un bug che mi è stato fatto notare per e-mail: lo script non funzionava bene se venivano inseriti più di 10 sottomenu. Ora è tutto Ok, ma se doveste trovare qualche altro errore, scrivetemi.
Questo script è stata per me un'autentica sorpresa! Il giorno stesso che l'ho pubblicato nel sito a sostituzione del vecchio menu classico ho ricevuto varie richieste di riutilizzo.
La cosa mi fa molto piacere ovviamente, e dunque in questo e nel prossimo StaffScript lo metto a vostra disposizione sia in versione "orizzontale" come l'ho usato io che verticale.
Ci sono due caratteristiche originali in questo menu:
- il fatto che quando un link viene cliccato il livello lampeggia;
- ed il fatto che quando il mouse lascia la colonna dei sottomenu, dopo un secondo tutta la colonna viene colorata del colore "attivo" prima di essere nascosta.
La prima caratteristica l'ho copiata dai menu di sistema dei Macintosh! Mi sembra che anche Win2K abbia adottato questo artificio grafico... spero che nessuno ci abbia messo il Copyright, comunque a me piace! :-)
Lo script è un po' complicato da commentare linea per linea, quindi mi limiterò a dirvi come personalizzarlo, e poi a descrivere le funzioni principali senza approfondirle troppo.
La prima parte delle personalizzazioni riguarda ovviamente i colori e la posizione.
Nello script (comunque ben commentato) troverete per prime queste cinque variabili:
var ron="#c00000"; Colore al MouseOver (Rosso in JsDir)
var roff="#000000"; Colore di default (Nero in JsDir)
var leftmargin=170; Distanza dal margine sinistro della pagina
var topmargin=70; Distanza dal margine superiore della pagina
var largo=125; Larghezza dei layers, quindi distanza (orizzontale) fra i sottomenu
Seguono tre array (a loro volta costituiti da array) che rappresentano tutti i dati del menu.
Il primo (
voci()) contiene i testi visualizzati dai bottoni, nel caso di JsDir sono ad esempio:
JavaScript (sottomenu del menu principale) che contiene "StaffScripts, UserScripts, FlyScripts, ecc. che sono le voci del sottomenu.
È importante notare subito una cosa che riguarda la struttura degli array, da questa dipende la struttra del menu. Ogni array ("voci()", "links()" e "wst()") ha lo stesso numero di elementi, che a loro volta sono altri array costituiti per ogni array principale dallo stesso numero di elementi. Nel nostro menu, l'array "voci" ha 4 elementi (voci[0], voci[1], voci[2], voci[3]) che a loro volta sono array costituiti da:
voci[0] --> 6 elementi
voci[0] --> 7 elementi
voci[0] --> 5 elementi
voci[0] --> 7 elementi
Gli altri due array principali ("links()" e "wst()")
hanno la stessa identica struttura e contengono, rispettivamente, i links HTML ed il testo visualizzato nella barra di stato quando il mouse è sulla voce del menu. Questi tre array, in pratica, servono a ricostruire i classici link:
<A HREF="pagina.html" onMouseOver="window.status='pagina'>Pagina</A>
Il link
Home è inserito di default come primo elemento del menu principale, se non lo volete è necessario elminare (o commentare) nello script il
document.write() che lo scrive nel documento, che è il primo delle due sezioni per NN ed IE e scrive il layer (o DIV) "
mtop" come vedremo subito.
Invece il primo elemento degli array non è un link vero e proprio, ma rappresenta allo stesso tempo, sia le voci del menu principali, che il "titolo" dei sottomenu. Non essendo un link non gli ho collegato la funzione che attiva il link, quindi nell'array "links()" gli elementi, pur dovendo essere presenti sono delle stringhe vuote. Fate attenzione a questo particolare, perché se omettete questi elementi vuoti degli array otterrete che la prima voce del sottomenu aprirà il link della seconda, e così via, fino all'ultima che... non aprirà niente, perché non troverà un elemento nell'array!!!
Questo è quanto. L'ultima cosa da dire prima di commentare lo script è che per lo stile dei testi ho usato dei CSS (nello script vedrete degli attributi
CLASS) che troverete all'interno nel file .js nello ZIP da scaricare, e che dovrete riportare nel documento, eventualmente modificandoli a vostro gusto.
Qualche parola sullo script.
Dopo le variabili e gli array troverete il ciclo che scrive i livelli per NN (
LAYER) e per IE (
DIV). Non ho supportato Netscape 6 perché personalmente ho preferito disinstallarlo dal mio PC. Prima o poi uscirà una versione "decente" del programma che avrà il diritto di chiamarsi "browser", io comunque non l'ho provato e non l'ho inserito nella tabella del BrowserCheck che trovate in fondo alla scheda! :-)
Ultimora! Sembra che funzioni anche per NN6 grazie al taroccaggio eseguito da Paolo Carena :-)
I
document.write() si preoccupano di scrivere nel documento HTML i livelli posizionandoli in base alla posizione delle voci negli array, e comunque ponendo il link "Home" alle coordinate specificate all'inizio dello script fra le variabili di personalizzazione. I livelli seguenti si posizionano di conseguenza.
Delle funzioni che seguono, la prima che ci interessa è
coloratutti(col). Se il parametro "col" ha valore
true il colore delle voci del sottomenu sarà il colore "attivo" altrimenti sarà quello di default. Questa funzione è comandata dalla funzione che la precede:
NascondiMenu(). Come vedete, i menu vengon prima resi attivi, poi, dopo 200 ms, vengono spenti, e successivamente (
showdeps(last,false)) nascosti. I questo modo si realizza la seconda delle caratteristiche "originali" che vi ho menzionato all'inizio della scheda.
Subito prima troviamo un
setInterval(). Questo ciclo lavora in congiunzione con la variabile globale
conta. Questa variabile inizia con valore "0" nella dichiarazione, e viene gestita dall'event-handler onMouseOver e onMouseOut direttamente nei livelli. Viene incrementata se uno qualsiasi dei livelli (sia dei sottomenu che del menu principale) è attivo, decrementata quando il livello non è più attivo. Di fatto assume volta per volta valore "0" o "1". Il funzionamento è un po' intricato, comunque più o meno è come segue: quando il mouse è su un livello (o link per NN) onMouseOver esegue
conta++ che fa assumere alla variabile il valore "1", quando il mouse si sposta, l'onMouseOut la decrementa (
conta--) e la variabile torna a "0". Resta a "0" se il mouse è andato fuori dai menu, ma se invece si è spostato su uno dei sottomenu, o su un'altra voce del menu principale riassume immediatamente valore 1. A che serve tutto 'sto giro? Semplice: a nascondere i sottomenu quando il mouse lascia i livelli. Infatti il
setInterval() esegue ogni secondo la funzione
NascondiMenu() che fa il suo lavoro solo quando la variabile è a "0" quindi quando il mouse ha lasciato
tutti i sottolivelli. Se provate a togliere la riga del setInterval() vedrete che i livelli non si chiudono più!
Successivamente troviamo la funzione
MostraMenu(), attivata dai livelli del menu principale, che usa due variabili: "last" e "n", quest'ultima rappresenta il sottomenu da aprire, quindi questa funzione nasconde l'ultimo menu aperto ("last"), apre quello voluto ("n") e ricorda quest'ultimo ("last=n").
La funzione successiva (
showdeps(n,act)), attivata anche questa dai livelli del menu principale, si preoccupa di visualizzare (se act=true) o nascondere (se act=false) il sottomenu "n", non è altro che un ciclo che cambia lo stato (visible/hidden) dei livelli. Anche qui entra in gioco la variabile
conta, ma per un motivo più strano. Non sto a spiegarvelo, ma ci sono particolari situazioni (dipendenti da "come" viene spostato il mouse) per cui verrebbe chiuso il menu lasciato, ed il menu da aprire verrebbe aperto ed immediatamente richiuso anch'esso. Mettere qui il controllo se
conta==0 ha risolto questo malfunzionamento.
Segue la funzione
vai() che si occupa di caricare il link cliccato. Alla variabile "lev" viene assegnato il livello corrente, e poi con una serie di
setTimeout() il livello viene colorato alternativamente del colore "attivo" e "default". L'ultimo setTimeout() cambia la location del browser.
Le ultime due funzioni
mroll() ed
unmroll() si occupano di fare il rollover dei colori nel livello su cui è posizionato il mouse, ed anche queste sono banali operazioni di cambio della proprietà bgColor/background (rispettivamente per NN ed IE) in DHTML. Alla funzione
mroll() viene passato il nome del livello da gestire sotto forma di stringa, quindi per scegliere la frase da visualizzare nella status bar ho usato il metodo substr() applicato al parametro per ricavare gli indici degli arrays.
Non dimenticate infine di inserire l'istruzione
onResize="self.location.reload()" nel tag <BODY...> del documento.