Qualche settimana fa ho riletto in it.comp.lang.javascript una richiesta abbastanza frequente: come implementare una "barra di navigazione", cioè una serie di links che siano in grado di dare all'utente un'idea del "dove" si trovi nel sito. La stessa, per intenderci, che vedete in tutte le pagine di JsDir.com: "La tua posizione nel sito: ...". Alcuni la chiamano "Bussola", altri "Briciole di pane", ho preferito chiamare questo script
Site Pointer perché di fatto è un puntatore all'interno del sito
Normalmente questa barra è facile da implementarsi quando si lavora lato server, perché dai database è facile risalire alle pagine genitore di quella visualizzata, oppure, se le pagine del sito si ramificano in sottocartelle, basta leggere la location, tirar fuori il path completo della pagina visualizzata e, lavorando di
substring() e
replace() tirar fuori una barra senza complicarsi tanto la vita.
Lo script che vi propongo è invece assolutamente adatto ad una situazione più comune nella quale tutti i files HTML sono residenti nella stessa cartella (tipicamente la root del sito), anche se può tranquillamente essere adattato ad un sito ramificato in cartelle, semplicemente includendo i vari path.
Lo script usa una tecnica nuova per chi mi segue da tempo: una funzione
ricorsiva, cioè una funzione che richiama più volte se stessa per giungere ad un risultato finale. Occhio all'uso di questo tipo di funzioni: è facilissimo cadere in errori di "Stack overflow" se la funzione non trova mai verificata la condizione di uscita, quando fate i vosti esperimenti inizializzate sempre un contatore e nell'
if() che controlla se la funzione deve richiamarsi controllate anche il contatore, se è arrivato ad un numero da voi prestabilito (cioè se la funzione è già stata eseguita un tot di volte) fatela terminare. Explorer (noto per i suoi bug dovuti proprio a problemi di controllo dello stack) potrebbe anche crashare!!!
Alla fine della descrizione (nella sezione DEBUG) vedrete un esempio di come debuggare una vostra funzione ricorsiva.
Lo script va incluso nella vostre pagine, sotto forma di script incluso, nel punto esatto in cui volete che compaia la barra come se fosse una qualsiasi immagine, vedete il sorgente di una qualsiasi pagina di prova come esempio.
Iniziamo vedendo com'è fatto l'array che contiene le informazioni su
tutte le pagine del sito.
Ho sottolineato subito "tutte" perché dovrete ovviamente avere l'accortezza di elencare la totalità delle pagine, altrimenti in alcune la barra non verrebbe visualizzata.
Memorizzeremo, in un file incluso, un array che contiene i dati di tutte le pagine, dati che saranno a loro volta rappresentati da un array che ha questa struttura:
[ "Nome della pagina" , "(path)NomeFile della pagina" , "(path)NomeFile della pagina genitore" ]
Dove
Nome della pagina è banalmente il nome visibile della pagina a video cioè il testo del link che andremo a creare, se guardate la barra di questa schermata sarà ad esempio "Script085".
(path)NomeFile della pagina è il nome del file HTML della pagina in questione (sempre facendo riferimento a questa schermata potrebbe essere "script085.asp") eventualmente preceduto dal path del file rispetto alla root scritto con la sintassi normale, per questa schermata avremmo inserito "/staffscripts/script085.asp".
Il terzo parametro è sintatticamente identico al secondo, ma rappresenta la pagina
genitore. Per questa schermata il genitore dovrebbe essere "scripts.asp", o, più precisamente includendo il path, dovrebbe essere "/staffscripts/scripts.asp".
In pratica dovendo inserire nell'array i dati della pagina che stiamo leggendo dovremmo scrivere:
[ "Site Pointer" , "/staffscripts/script085.asp" , "/staffscripts/scripts.asp" ]
Il nome della pagina genitore è l'elemento che ci consentirà di mettere in relazione le pagine l'una con l'altra fino ad arrivare alla homepage, che, non essendo figlia di nessun'altra pagina, la indicheremo come genitore di se stessa, quindi, facendo riferimento a JsDir.com, scriveremmo:
[ "Homepage" , "/default.asp" , "/default.asp" ]
Inserendo in quest'esempio anche la pagina intermedia fra questa e l'homepage (cioè la "scripts.asp" che elenca tutti gli Staffcripts), aggiungeremmo la riga:
[ "StaffScripts" , "/staffscripts/scripts.asp" , "/default.asp" ]
quindi avremmo queste tre righe nel nostro array:
[ "Homepage" , "/default.asp" , "/default.asp" ]
[ "StaffScripts" , "/staffscripts/scripts.asp" , "/default.asp" ]
[ "Site Pointer" , "/staffscripts/script085.asp" , "/staffscripts/scripts.asp" ]
notiamo i nomifile che ho evidenziato in rosso e verde: sono ovviamente assolutamente identici (altrimenti lo script non funzionerà a dovere), e mettono in relazione: il nomefile in rosso la pagina "Site Pointer" con la pagina "StaffScripts" e (quelli in verde) la pagina "StaffScripts" con la "Homepage".
Fate attenzione a valutare la necessità dell'uso dello slash iniziale.
Ovviamente vogliamo usare un'unico script per tutto il sito, dunque lo posizioneremmo nella root e lo includeremo in tutte le pagine con
<script src="/PointerScript.js"></script>. Per far si che i collegamenti a ritroso creati dallo script siano validi, tutti i path dovranno essere assoluti, quindi riportare le cartelle in cui è contenuto il file ed iniziare con "/" in modo che il browser richieda correttamente le pagine al server.
Nello script di esempio, invece, ho dovuto usare dei collegamenti relativi, perché posiziono gli esempi in sottocartelle della cartella "/staffscripts" della root (l'esempio si trova in [
http://www.jsdir.com]/staffscripts/script085/ ).
Usando un path assoluto il browser avrebbe cercato le pagine d'esempio nella root invece che nella cartella.
Tutta questa filippica sul path è necessaria per mettervi in guardia contro un problema che potrebbe presentarsi durante lo sviluppo: il browser (in particolare IE) potrebbe darvi dei problemi se non usate un server locale durante lo sviluppo (PWS, Apache, o altri), dato che probabilmente non svilupperete il sito nella root del vostro hard disk (C:\) ma in una cartella (C:\documenti\siti\miosito), se avete i files in sottocartelle e tentate di usare un path assoluto
durante lo sviluppo il browser cercherà i files nella root (IE potrebbe anche protestare per l'uso di / invece che \ nei path). Avendo files in cartelle, non potrete dunque provare lo script in locale prima di mandarlo in rete, mentre se tutti i files sono nella root del sito (che in locale è la cartella \miosito), non avrete necessità di path assoluti e potrete scrivere i nomifile come nello script d'esempio.
Questo problema non si pone se invece sviluppate usando un server web anche in locale, l'uso di un path assoluto sarà ancora necessario se avete delle cartelle, ma non darà problemi perché ci penserà il server caricare il sito dalla giusta cartella, che poi è quella da cui carica http://localhost: durante le vostre prove.
Se non avete cartelle anche usando un server in locale non ci sarà necessità di usare lo / davanti al nome del file.
Prestate attenzione quindi
solo se non usate un server in locale ed avete i files sparsi in cartelle. Controllate con la massima attenzione lo script prima di mandarlo in rete, appena possibile vedrò di costruire una pagina con uno script di test che consenta di provare l'array prima ancora di inserirlo nelle pagine.
Tornando a noi vediamo com'è strutturato l'array d'esempio:
var pagine = [
[ "HomePage" , "index.html" , "index.html" ],
[ "JavaScript" , "javascript.html" , "index.html" ],
[ "StaffScripts" , "staffscripts.html" , "javascript.html" ],
[ "Menu" , "menu.html" , "staffscripts.html" ],
[ "Menu a tendina" , "menutendina.html" , "menu.html" ],
[ "Menu a tendina Standard" , "menutendinastandard.html" , "menutendina.html" ],
[ "Menu a tendina Verticale" , "menutendinaverticale.html" , "menutendina.html" ],
[ "Menu a tendina Orizzontale" , "menutendinaorizzontale.html" , "menutendina.html" ],
[ "Menu ad albero" , "menualbero.html" , "menu.html" ],
[ "Menu Select" , "menuselect.html" , "menu.html" ],
[ "Menu a cascata" , "menucascata.html" , "menu.html" ],
[ "UserScripts" , "userscripts.html" , "javascript.html" ],
[ "Documenti" , "documenti.html" , "index.html" ],
[ "F.A.Q. & Answers" , "faq.html" , "documenti.html" ],
[ "Tutorials" , "tutorials.html" , "documenti.html" ],
[ "Validazione e-mail" , "validamail.html" , "tutorials.html" ],
[ "Temporizzatori" , "times.html" , "tutorials.html" ],
[ "Finestre" , "windows.html" , "tutorials.html" ],
[ "Oggetto Date" , "data.html" , "tutorials.html" ],
[ "Links" , "links.html" , "documenti.html" ],
[ "Microsoft" , "microsoft.html" , "links.html" ],
[ "Netscape" , "netscape.html" , "links.html" ],
[ "Altri" , "altri.html" , "links.html" ],
[ "Contatti" , "contatti.html" , "index.html" ],
[ "Staff" , "staff.html" , "contatti.html" ],
[ "Collaboratori" , "collaboratori.html" , "contatti.html" ],
[ "Credits" , "credits.html" , "contatti.html" ]
];
L'array principale è ovviamente "pagine" e, una per riga, ho riportato tutte le pagine che compongono il sito d'esempio, ricalcando alcune sezioni di JsDir.com.
Notate (questa sarà davvero l'ultima parentesi sul path) che
ho dovuto sistemare tutti i files insieme anche se nella realtà in JsDir.com andrebbero in cartelle, ed alcune sezioni (i Links) non sono neanche pagine separate.
La necessità di questo è presto detta: innanzitutto non potevo sparpagliare nel sito reale le varie pagine di test, ma era necessarie tenerle raggruppate nella cartella di questo StaffScripts, ed anche se avessi voluto replicare nella cartella /script085 la struttura del sito (mettendo delle sottocartelle /staffscripts, /tutorials, etc) avrei dovuto usare un path assoluto e quindi avrei dovuto inserire, nell'array di test, anche il percorso reale dei files in JsDir.com.
A questo si aggiunga il fatto che non ho ovviamente la più pallida idea di
dove andate a salvare gli esempi che scaricate nel vostro hard disk, quindi l'unica maniera di far funzionare tutto l'ambaradan sui miei pc e server di sviluppo, nel sito e nel vostro pc era quello di usare un path relativo.
Tornando all'array vediamo che ho usato le parentesi quadre
[ ] per dichiarare gli array invece del consueto
new Array(), una scelta assolutamente di comodo per mantenere il codice un po' più pulito e comprensibile.
Ho inoltre indentato le righe per lo stesso motivo: riconoscere ad occhio le interdipendenze fra pagine "genitore" e "figlio" senza dover necessariamente andare a controllare i nomifile per verificare e manutenere l'array.
Fate attenzione a non dimenticare l'ultima parentesi quadra (quella isolata alla fine) perché chiude l'array principale "pagine" ed a non mettere la virgola dopo l'ultimo array interno (quello di "Credits" nell'esempio), altrimenti l'interprete JavaScript si aspetterà un'ulteriore elemento di "pagine", cioè un altro array, e non trovandolo genererà un errore.
L'uso del nomefile come "collegamento" fra genitori e figli potrebbe a prima vista risultare scomodo (ed in effetti lo è perché impone maggiore attenzione nel non commettere errori di battitura), ma comporta un vantaggio enorme: consente di
rendere indipendenti i singoli array dalla loro posizione all'interno dell'array principale ("pagine"), infatti notate che non c'è alcun
numero negli array riferibile agli indici di "pagine". Invece di replicare la struttura del sito nell'array (come ho fatto per chiarezza nell'esempio), potrete tranquillamente spostare in su e in giù le righe per raggrupparle come a voi sembra più comodo, e quando avrete necessità di aggiungere una pagina o un'intera sezione al sito (e dunque all'array) potrete tranquillamente accodare le righe necessarie a quelle già presenti, penserà lo script ad interpretarlo correttamente.
Vediamo il codice dello script:
var TestoIniziale="Sei in: ";
var pagine = [
["HomePage","index.html","index.html"],
. . .
. . .
["Credits","credits.html","contatti.html"]
];
var percorso="";
var filename = document.URL.replace(/\\/g,"/");
CercaSitePointer(filename.substr(filename.lastIndexOf("/")+1));
document.write("<span class='PLink'>"+TestoIniziale+percorso.substr(3)+"</span>");
function CercaSitePointer(str)
{
for (var i=0 ; i<pagine.length ; i++)
if (pagine[i][1] == str)
{
percorso=" / <a href='"+str+"' class='PLink'>"+pagine[i][0]+"</a>"+percorso;
if (pagine[i][2] != str)
CercaSitePointer(pagine[i][2]);
}
}
La prima variabile (
TestoIniziale) serve, appunto, come inizio della riga, nell'esempio è "Sei in: ", in questa pagina (come in tutto il sito) l'avrei valorizzata con "La tua posizine nel sito: ". Va da se che potete lasciarla vuota se necessario.
Questa variabile, insieme all'array, sono le uniche due cose da personalizzare, font e colori infatti vengono decisi tramite una classe di stile ("PLink") che nello script d'esempio è:
.PLink, .PLink:visited, .PLink:active, .PLink:link {
font-family : verdana ;
font-size : 12px ;
text-decoration : none ;
color : #c00 ;
background-color : transparent ;
font-weight : bold ;
}
.PLink:hover {
color : #080 ;
text-decoration : underline ;
}
classe che ovviamente dovrete aggiungere al vostro foglio di stile o includere con la solita sintassi <link rel="stylesheet" type="text/css" href="/PointerStyles.css"> come vedrete nelle pagine d'esempio.
Dopo l'array troviamo una variabile stringa inizialmente vuota ("percorso") che verrà riempita dalla funzione seguente con il necessario codice HTML.
A seguire un workaround necessario per IE: se usato off-line (in fase di sviluppo e senza un server) funziona come Esplora Risorse usando il backslash ( \ ) invece del normale slash ( / ) per separare cartelle e files. Nella variabile
filename recuperiamo comunque la URL (che in questa situazione sarà il path windows-like del file nell'hard disk) e sostituiamo la barra rovesciata con quella normale, ricreando così la situazione "reale" di funzionamento sul server... niente di nuovo insomma... IE ci obbliga sempre a porre rimedio alle sue idiosincrasie :-(
Spero, ma non posso verificare, che questo problema non si presenti con altri sistemi operativi.
Poi finalmente invochiamo l'unica funzione di questo script:
CercaSitePointer() passandogli come parametro il solo nome del file HTML.
lastIndexOf() funziona in modo identico al più usato
indexOf() solo che cerca il carattere o la stringa voluti iniziando dalla fine della stringa cui viene applicato invece che dall'inizio.
La funzione è poi semplicissima.
Il ciclo
for () esplora tutto l'array "pagine" in cerca della stringa
str (il nomefile ricevuto dalla funzione) fra i secondi elementi degli array interni: cioè va a cercare fra i
NomeFile della pagina che abbiamo già incontrato discutendo dell'array.
Appena trova il nome cercato (
if (pagine[i][1] == str) ) per prima cosa aggiunge il link alla variabile
percorso usando lo stesso nome file cercato come link ed il primo parametro come testo del link (il
Nome della pagina che abbiamo già visto). Aggiungendo il link, l'utente del nostro sito dovrà semplicemente cliccare nella barra per salire ad un livello precedente.
Fatto questo confronta il terzo parametro con il nomefile cercato (sempre
str), e qui sta il bello!
Se il terzo parametro
è diverso dal nome cercato la funzione richiama se stessa andando a cercare il nomefile indicato nel terzo parametro cioè
il nomefile genitore.
Riporto qui una porzione dell'array visto sopra per non obbligarvi a scrollare:
var pagine = [
[ "HomePage" , "index.html" , "index.html" ],
[ "JavaScript" , "javascript.html" , "index.html" ],
[ "StaffScripts" , "staffscripts.html" , "javascript.html" ],
[ "Menu" , "menu.html" , "staffscripts.html" ],
[ "Menu a tendina" , "menutendina.html" , "menu.html" ],
[ "Menu a tendina Standard" , "menutendinastandard.html" , "menutendina.html" ],
[ "Menu a tendina Verticale" , "menutendinaverticale.html" , "menutendina.html" ],
[ "Menu a tendina Orizzontale" , "menutendinaorizzontale.html" , "menutendina.html" ],
. . .
];
Se ad esempio abbiamo nel browser la pagina "menutendinaverticale.html" (v. riga in grassetto nell'array) la funzione va a cercare nell'array la riga corrispondente, e troverà come terzo valore il nomefile "menutendina.html". La funzione dunque richiama se stessa andando a cercare come secondo parametro "menutendina.html". Troverà questo nomefile due righe più sopra (ricordate che comunque la funzione ricomincia da capo ogni volta che viene invocata, anche da se stessa), e confrontando il nome cercato con il terzo valore troverà ancora un nomefile diverso ("menu.html"), richiamerà di nuovo se stessa e questa volta troverà che il terzo parametro è "staffscripts.html", richiama ancora di nuovo se stessa cercando "staffscripts.html"... e così via finché non arriva a cercare "index.html".
A questo punto si fermerà: infatti il confronto che la obbliga a richiamarsi sarà falso perché nel caso della homepage il terzo valore è uguale al secondo, cioè alla stringa "str" che la funzione sta cercando, quindi
la funzione non si richiamerà più da sola. ed uscirà da questo circolo vizioso.
A questo punto la variabile "percorso" conterrà tutto il codice HTML inserito dalla funzione, quindi per "menutendinaverticale.html" conterrà:
/ <a href='index.html' class='PLink'>HomePage</a>
/ <a href='javascript.html' class='PLink'>JavaScript</a>
/ <a href='staffscripts.html' class='PLink'>StaffScripts</a>
/ <a href='menu.html' class='PLink'>Menu</a>
/ <a href='menutendina.html' class='PLink'>Menu a tendina</a>
/ <a href='menutendinaverticale.html' class='PLink'>Menu a tendina Verticale</a>
Se seguite a ritroso (dal basso verso l'alto) questo codice, che per comodità di lettura ho spezzato riga per riga, ritroverete il percorso che ha fatto la funzione e che ho appena descritto.
Avendo la funzione terminato di lavorare lo script esegue la riga successiva alla chiamata originaria, quindi stamperà nella pagina il codice HTML contenuto in "percorso" contornandolo da un tag <span class="PLink"> ... </span> per poter colorare anche le barre che separano le varie pagine e che sono state inserite dalla funzione, ed anteponendogli il
TestoIniziale.
Dal momento che lo script inserisce sempre una barra prima del link (nella funzione), prima di stampare il codice ho eliminato primi tre caratteri (spazio barra spazio). Se invece volete comunque lasciarli basta togliere dal document.write() la porzine
.substr(3) (attenzione: anche il punto!)
Fine dei giochi ed anche di questa lunga descrizione.
Spero di non aver annoiato nessuno, ma visto che, come dicevo all'inizio, è la prima volta che vediamo una funzione ricorsiva in JsDir.com ho scelto di addentrarmi molto nei dettagli per essere il più chiaro possibile... e non ho ancora finito :-)
Due sole cose mi restano da dire.
La prima: se invece di testi volete usare delle immagini (cosa che comunque vi sconsiglio perché appesantirebbe il caricamento della pagina), negli array dovrete sostituire la prima voce con il nome dell'immagine (ad esempio avendo per l'homepage un'immagine "home.gif" farete:
["home","index.html","index.html"],) e modificare di conseguenza la riga della funzione che riempie la variabile "percorso":
percorso=" / <a href='"+str+"' class='PLink'><img src='"+pagine[i][0]+".gif'></a>"+percorso;
Volendo usare un'immagine al posto della barra ("separatore.gif") modificherete ulteriormente in questo modo:
percorso="<img src='separatore.gif'><a href='"+str+"' class='PLink'><img src='"+pagine[i][0]+".gif'></a>"+percorso;
ed ovviamente modificare anche il numero di caratteri strippati da substr() nel document.write(), qui bisognerebbe togliere 27 caratteri e non più 3 perché tanti sono i caratteri che servono per il tag img del separatore (<img src='separatore.gif'>).
D E B U G
La seconda è un avviso molto importante: prestate la MASSIMA ATTENZIONE a non duplicare nell'array i nomifile o i nomi dei files genitori, nel senso che lo stesso nomefile non puo' comparire due o più volte come secondo parametro ed il nome dei files genitore non deve comparire due o più volte come terzo.
La funzione impazzirebbe perché entrerebbe in loop infinito finché l'interprete non esaurisce lo spazio dello stack (una particolare area di memoria che consente l'uso della ricorsione) fino a dare un errore a runtime ed, in alcuni casi come è successo a me, addirittura a provocare il crash del browser.
Se doveste avere questo tipo di problema e non riuscite a trovare l'errore, commentate lo script (ad esclusione dell'array) ed usate quest'altro (le porzioni in rosso sono quelle aggiunte per il debug):
var percorso="";
var contacicli=0;
var filename = document.URL.replace(/\\/g,"/");
document.write("<pre>Sto cercando: "+filename.substr(filename.lastIndexOf("/")+1)+" <hr>");
CercaSitePointer(filename.substr(filename.lastIndexOf("/")+1));
document.write("<hr><span class='PLink'>"+TestoIniziale+percorso.substr(3)+"</span></pre>");
function CercaSitePointer(str)
{
contacicli++;
for (var i=0 ; i<pagine.length ; i++)
if (pagine[i][1] == str)
{
percorso=" / <a href='"+str+"' class='PLink'>"+pagine[i][0]+"</a>"+percorso;
document.write(i+" - "+str+" - "+percorso +"<br>");
if (pagine[i][2] != str && contacicli < 10)
CercaSitePointer(pagine[i][2]);
}
}
Lo script così modificato stamperà per prima cosa il nomefile della pagina che viene cercato, poi all'interno della funzione il document.write() visualizzerà:
- l'indice dell'array "pagine" in cui il primo
if () della funzione ha trovato la pagina cercata;
- il nomefile cercato;
- il "percorso" che è stato costruito fino a quel momento.
Il nomifile e l'indice vi consentiranno di scoprire quando la funzione va a cercare dei nomefile che ha già trovato.
Come vedremo subito
è assolutamente impossibile che ci siano due nomefile uguali, quindi dovrete semplicemente controllare nella schermata che vi si presenterà (partendo dall'alto ovviamente) quando ricompare un nome file (o un indice) che è già comparso. L'indice alla riga superiore vi indicherà quale degli array interni (ricordate di contare partendo da zero!) contiente un
nome del file genitore sbagliato.
Basterà controllare la riga individuata e correggerla per eliminare il problema.
La funzione così modificata non impazzirà andando in loop, perché insieme al normale controllo, nell'
if () interno controlliamo anche il contatore
contacicli, e se la funzione si sarà richiamata già 10 volte uscirà comunque.
Per inciso: il valore 10 di controllo dovrebbe essere più che sufficiente per il debug, perché raramente un sito si svilupperà in più di 10 sottosezioni, neanche DMOZ o Yahoo arrivano a tanto se ben ricordo... comunque potrete sempre aumentarlo.
Potete essere assolutamente certi che il problema sarà un nomefile duplicato (come genitore) perché, come accennavo sopra, è impossibile che questo succeda: sia che abbiate i files del sito in una sola cartella (la root del sito ad esempio), sia che ce li abbiate in varie sottocartelle, è impossibile ovviamente creare due files o due cartelle uguali nel FileSystem di qualunque sistema operativo, dunque è impossibile che abbiate due files diversi con lo stesso nome e/o percorso.
D'altronde non avrebbe senso duplicare un nomefile o una cartella, quindi:
- se avete tutti i files in una sola cartella (root) non avrete indicato nell'array le cartelle perché l'array sarà simile a quello dell'esempio e l'unicità del nomefile sarà garantita dall'unicità del file nella cartella;
- se avete i files in cartelle diverse, il nome del file potrebbe anche essere uguale, ma il valore nell'array dovrà essere unico per l'unicità del nome della cartella, quindi nell'array ancora una volta non possono esserci valori uguali come secondo valore o come terzo valore (saranno invece uguali
un secondo con
un terzo per la struttura dell'array).
In definitiva l'unica maniera per far impazzire lo script è indicare come padre di un elemento di livello superiore un file di livello inferiore, ad esempio:
var pagine = [
["HomePage","index.html","index.html"],
["JavaScript","javascript.html","menu.html"],
["StaffScripts","staffscripts.html","javascript.html"],
["Menu","menu.html","staffscripts.html"],
["Menu a tendina","menutendina.html","menu.html"],
["Menu a tendina Standard","menutendinastandard.html","menutendina.html"],
["Menu a tendina Verticale","menutendinaverticale.html","menutendina.html"],
["Menu a tendina Orizzontale","menutendinaorizzontale.html","menutendina.html"],
["Menu ad albero","menualbero.html","menu.html"],
["Menu Select","menuselect.html","menu.html"],
["Menu a cascata","menucascata.html","menu.html"],
qui ho (intenzionalmente :-) sbagliato il "padre" della voce "JavaScripts" (la numero 1 dell'array, quindi la 2° riga) indicando come "padre" una voce inferiore, e lo script impazzisce perché quando arriva alla voce "JavaScript" cerca come padre "Menu", lo trova e ne carca il padre "StaffScripts" che rimanda a "JavaScript" che rimanda a "Menu"... eccetera. Lo script inizia a ciclare indefinitamente fra le righe in grigio per colpa di quell'errore (il valore giusto era invece "index.html" perché la homepage è il genitore legittimo di JavaScript).
Lo script così modificato visualizza nel browser:
Sto cercando: menutendinaverticale.html
6 - menutendinaverticale.html - / Menu a tendina Verticale
4 - menutendina.html - / Menu a tendina / Menu a tendina Verticale
3 - menu.html - / Menu / Menu a tendina / Menu a tendina Verticale
2 - staffscripts.html - / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
1 - javascript.html - / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
3 - menu.html - / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
2 - staffscripts.html - / StaffScripts / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
1 - javascript.html - / JavaScript / StaffScripts / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
3 - menu.html - / Menu / JavaScript / StaffScripts / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
2 - staffscripts.html - / StaffScripts / Menu / JavaScript / StaffScripts / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
Sei in: StaffScripts / Menu / JavaScript / StaffScripts / Menu / JavaScript / StaffScripts / Menu / Menu a tendina / Menu a tendina Verticale
Notiamo che ad un certo punto (6° riga) ricompare il valore 3 già apparso alla 4° riga: il numero alla riga precedente (1) ci indica la riga in cui abbiamo sbagliato
E questo era un errore di nomefile duplicato fra i genitori. Se invece per errore doveste duplicare un nome file fra i nomi dei files (secondo valore degli array) lo script non impazzirà, ma non funzionerà per la voce in cui compare erroneamente il nome del file e per tutti i files figli.
Il consiglio principe (dovrebbe essere superfluo... ma ormai ho superato me stesso con la lunghezza di questa descrizione quindi tanto vale.... :-) è: prima di andare on-line controllate attentamente tutte le pagine del sito, verificando che i percorsi vengano scritti correttamente, purtroppo qui non si tratta di un menu che se funziona su una pagina funziona su tutte, ma di uno script che deve funzionare su ogni singola pagina!!!.