È una necessità comune passare da una pagina "a tutto browser" ad una a frameset, ma caricando direttamene uno o più frame in particolare in relazione al link cliccato.
Risulta ovviamente più comodo per il visitatore ritrovarsi il frameset già pronto senza dover ulteriormente selezionare.
In questo script vediamo come ottenere questo risultato.
Ovviamente il punto di partenza è una serie di links che non puntano direttamente al frameset ma fanno una chiamata ad una funzione JavaScript alla quale passano
il nome della pagina HTML da aprire in alto.
La funzione carica un frameset ponendo il nome del file HTML nella querystring che poi un'altra funzione userà per riempire il frame superiore.
La funzione di chiamata (contenuta nello script incluso
OpenFrames.js) è ovviamente un banale cambio di location:
function ApriFrameset(File)
{
self.location.href="frameset.html?"+File+".html";
}
riceve il nome della pagina da aprire nel parametro
File, accoda l'estensione (inutile scriverla nei links) e la aggancia alla URL come un parametro in QueryString.
I link sono semplicemente delle chiamate alla funzione JavaScript:
<a href="javascript:ApriFrameset('pagina1')">Link alla pagina uno</a>
Il codice della pagina frameset invece è questo:
<html>
<head>
<title>Frameset comandato</title>
<script type="text/javascript" src="OpenFrames.js"></script>
</head>
<frameset rows="90%,*" onload='CaricaFrame()'>
<frame name="contenuti" src="paginavuota.html" marginwidth="0" marginheight="0" scrolling="auto" frameborder="0" />
<frame name="footer" src="footer.html" marginwidth="0" marginheight="0" scrolling="auto" frameborder="0" />
</frameset>
</html>
Notiamo che nel frame
contenuti carichiamo una pagina vuota (
paginavuota.html appunto) che contiene solo i tag minimi per essere un documento HTML con solo uno spazio nel BODY.
Il motivo è semplicemente evitare un errore di
access denied. Verrebbe spontaneo caricare un
about:blank come src del frame contenuti, ma alcune versioni di Explorer (le più recenti sopratutto) genererebbero un errore perché lo script cercherebbe di cambiare una URL in un dominio che non è quello in cui gira lo script (il frameset sta sul server web, invece about:blank è sul computer locale dell'utente).
Caricando invece una pagina senza conenuti siamo al riparo da questo problema.
La funzione che si occupa di aggiornare il frame sta nello stesso script incluso ed è semplicemente questa:
function CaricaFrame()
{
parent.frames.contenuti.location.href=location.search.substr(1);
}
scatta al caricamento avvenuto del frameset in modo che il frame
contenuti sia già presente nel DOM del browser (esista cioè come oggetto su cui lavorare) e semplicemente legge la querystring eliminando il primo carattere "?" (
location.search.substr(1)) ricavandone il nome del file HTML, ad esempio "pagina1.html", e la posiziona nel frame cambiando la location.
L'approccio tramite onload() nel frameset è quello più sicuro per evitare di incorrere in errori di JavaScript, ma richiede un'accortezza: scattando a caricamento avvenuto ovviamente aspetterà che la pagina
footer.html sia stata completamente caricata, quindi è necessario mantenerla il più possibile leggera (in termini di KBytes, 5/7 al massimo comprese eventuali immagini, animazioni etc), sopratutto se questo script girerà sulla Rete, altrimenti il visitatore, vedendo una pagina vuota in alto, potrebbe pensare a qualche problema.
I link di navigazione ovviamente saranno corredati di
target come di consueto nell'uso di frames.
Due o più frames dinamici
Per usare invece due o più frames fissi (ad esempio un menu a sinistra ed un header in alto), sarà sufficiente, è ovvio, ridisegnare il frameset, mentre volendo ad esempio rendere "dinamico" anche il menu a sinistra, sarà sufficiente aggiungere il nome della pagina ai links sotto forma di un altro parametro:
<a href="javascript:ApriFrameset('pagina1','menusx1')">Link alla pagina uno</a>
e, supponendo di aver dato
name='menusx' al relativo frame, modificare le due funzioni come segue:
function ApriFrameset(File,Menu)
{
self.location.href="frameset.html?"+File+".html&"+Menu+".html";
}
function CaricaFrame()
{
var pagine = location.search.substr(1).split("&");
parent.frames.contenuti.location.href=pagine[0];
parent.frames.menusx.location.href=pagine[1];
}
la seconda funzione ricava un array "pagine" spezzando in un array il parametro ricevuto, e ne carica i due elementi nel giusto frame.