In seguito ad una richiesta specifica, ho realizzato questo tutorial su come creare dei test utilizzando il posizionamento degli oggetti in un documento.
Chiaramente vi sono altri modi (anche più raffinati) per realizzare quanto segue, ma per mantenere la compatibilità verso i principali browser (IE4 - IE5 - NN4 - NN6) ho realizzato lo script utilizzando gli eventi comuni a tutti i browsers indicati.
La realizzazione del documento e quindi degli oggetti da utilizzare è dinamica, quindi tutto si riduce ad uno script che può essere inserito in un file .js.
Lo scopo "pratico" è di realizzare degli oggetti che possano essere "spostati" con il mouse ed inseriti nella posizione tale da verificare la correttezza o meno dell'inserimento stesso, in modo da segnalare il superamento o meno del test.
Nell'esempio realizzato utilizziamo 3 livelli di colore diverso (verde, bianco, rosso) che andranno a costituire la bandiera italiana, inserendo tali oggetti in un riquadro sulla destra del documento.
Naturalmente nulla vieta che dentro i livelli possano esserci delle immagini.
Spostando gli oggetti con il mouse nella cella di destra , alla verifica del test , se gli elementi saranno inseriti correttamente, si riceverà un messaggio di test superato, al contrario di test non superato.
<html>
<head>
<SCRIPT LANGUAGE="Javascript">
Iniziamo lo script con il solito browser sniffer che rileva browser e versione:
var nome=(navigator.appName=="Microsoft Internet Explorer")?true:false;
var wt=nome?(navigator.appVersion.split(';').toString().split(" ").toString().split(',')[4] ):null;
var isie5=((wt)>=5 && nome)?true:false;
var isie4=((wt <5 && wt >=4) && nome)?true:false;
var isNS4=(document.layers)?true:false;
var isNS6=document.getElementById && (navigator.appName=="Netscape")?true:false;
//------------------------------------------------------------------
l'array colore definisce i colori dei livelli che creeremo per il test, in questo caso quelli della bandiera italiana.
colore=new Array('white','green','red');
l'array seq definisce la sequenza del posizionamento dei livelli nel riquadro di destra, in modo da dare il responso,
positivo o negativo, del test se non rispettata, comunque lo vedremo in seguito.
seq=new Array(100,50,150)
Con top_pos definisco la posizione top del primo livello
top_pos=20;
liv="";
vt=0;
gg=0;hh=0;
//------------------------------------------------------------------
Rileviamo le coordinate del mouse assegnando i valori ad ax e ay.
//--------------mouse ----------------------------------------------
var ax=0;
var ay=0;
if(isNS4 || isNS6){
window.captureEvents(Event.MOUSEMOVE);
window.onmousemove=move;
}
else if (isie4 || isie5)document.onmousemove=move;
function move(e){
if (isie4 || isie5)ax=window.event.clientX, ay=window.event.clientY;
else if (isNS4 || isNS6)ax=e.pageX, ay=e.pageY;
return ax;ay;
}
//---------------------------crea livelli-----------------
Creiamo i livelli ed il riquadro di destra dove inserirli per i vari browser.
function crea_div(){
if(isie4 || isie5 || isNS6){
Realizziamo il ciclo per creare i tre livelli che costituiranno le parti della bandiera.
for(i=0; i<colore.length; i++){
Assegnamo un id ciclico ai livelli.
id_liv=""+"a"+i;
La variabile liv memorizza i livelli che inseriremo poi con innerHTML nel documento.
liv+='<div id=\"'+id_liv+'\" style="position:absolute; height:100; width:48; border:ridge;
left:50; top:'+top_pos+';background:'+colore[i]+';"
onmousedown="sposta(\''+id_liv+'\')" onmouseup="rel(\''+id_liv+'\','+i+')"></div>'
top_pos=top_pos+150;
}
La variabile tab_test memorizza il livello di destra dove inseriremo i tre oggetti creati precedentemente.
tab_test='<div id="test" style="position:absolute; z-index:-1; top:100; left:400;">...
...<table border="2" cellpadding="5" cellspacing="0" width="160" height="110"><tr>...
...<td height="110"></td><td height="110"></td><td height="110"></td>...
...</tr></table><br><a href="javascript:ver_test()">Verifica Test</a><br>...
...<a href="javascript:self.location.reload()">Ripeti test</a></div>'
if(isie4){
document.all.princ.innerHTML=liv+tab_test;
}
else{
document.getElementById('princ').innerHTML=liv+tab_test;
}
}
}
if(isNS4){
Per NS4 realizziamo la stessa cosa utilizzando i layer invece dei div.
for(i=0; i<colore.length; i++){
id_liv=""+"a"+i;
liv+='<layer name=\"'+id_liv+'\" position="absolute" height=100 width=48 left=50; ...
...top='+top_pos+' bgColor=\"'+colore[i]+'\"
Utilizzando l'evento onmouseover è possibile attivare la cattura degli eventi onmousedown e
onmouseup come riportato nelle funzioni seguenti.
onMouseOver="esto(\''+id_liv+'\','+i+')"><table border="1" cellpadding="5" cellspacing="0" ...
...width="50" height="100"><tr><td height="100"></td></tr></table></layer>'
top_pos=top_pos+150;
}
tab_test='<layer name="test" position="absolute" z-index="-1" top=100 left=400>...
...<table border="2" cellpadding="5" cellspacing="0" width="160" height="110">...
...<tr><td height="110"></td><td height="110"></td><td height="110">...
...</td></tr></table><br><a href="javascript:ver_test()">Verifica Test</a>...
...<br><a href="javascript:self.location.reload()">Ripeti test</a></layer>'
document.write(liv+tab_test)
document.close();
Con NS4 per poter utilizzare onmousedown e onmouseup direttamente sui layer,
bisogna attivare la cattura degli eventi. In questo caso in base al livello scelto attiviamo la cattura degli eventi e la
riportiamo negli appositi livelli.
function esto(id,ii){
gg=id;hh=ii;
document.layers[id].captureEvents(Event.MOUSEDOWN);
document.layers[id].onmousedown = sposta1;
document.layers[id].captureEvents(Event.MOUSEUP);
document.layers[id].onmouseup = rel1;
function sposta1(){
Se premiamo il mouse su un livello di sinistra entra in azione la funzione sposta e
continuando a tenere premuto e spostando il mouse , il livello seguirà il mouse stesso finchè il pulsante verrà rilasciato.
A questo punto entra in gioco la funzione rel che stabilirà il posizionamento definitivo dell'oggetto.
Con IE4 IE5 e NN6 utilizziamo direttamente gli eventi suddetti perchè questi browser non richiedono la cattura degli eventi.
sposta(gg)
}
function rel1(){
rel(gg,hh)
}
}
}
//-----------------------sposta-------------------------------
In base all'oggetto spostiamo lo stesso associandogli le coordinate ax e ay del mouse come valori di top e di left.
Ripetiamo la funzione con setTimeout finché teniamo premuto il mouse.
function sposta(qq){
qw=qq;
liv_p=(isie5 || isNS6)?document.getElementById(qq).style:(isNS4)?...
...document.layers[qq]:document.all[qq].style;
liv_p.left=(ax-10)
liv_p.top=(ay-20)
qt=setTimeout('sposta(qw)',100)
}
//--------------------rilascia-------------------------------
Quando rilasciamo il mouse entra in azione la funzione rel alla quale passiamo i valori di id dell'oggetto
e l'indice del ciclo che ci servirà per stabilire la posizione originaria in caso di rilascio preventivo del mouse, per consentire il
ritorno degli oggetti alla posizione di partenza.
function rel(qq,ii){
Interrompiamo il ripetersi della funzione sposta.
clearTimeout(qt)
liv_r=(isie5 || isNS6)?document.getElementById(qq).style:(isNS4)?...
...document.layers[qq]:document.all[qq].style;
Verifichiamo la posizione top degli oggetti spostati, se non corrisponde all'altezza del riquadro di destra,
il livello ritorna alla posizione originale. Questo controllo può essere omesso o ampliato in modo da verificare altri parametri ed
agire di conseguenza.
if((parseInt(liv_r.top)< 100 || (parseInt(liv_r.top)> 110)) ){
liv_r.top=20+(ii*150)
liv_r.left=50
}
}
//--------------------------verifica-------------------------------
La verifica della successione degli oggetti vera e propria avviene quando si clicca sul link "Verifica test",
in quanto si verifica nella funzione sottostante la posizione degli oggetti come top e left di ognuno.
function ver_test(){
liv_t=new Array();
for(i=0; i<colore.length; i++){
idr=""+"a"+i
liv_t[i]=(isie5 || isNS6)?document.getElementById(idr).style:(isNS4)?...
...document.layers[idr]:document.all[idr].style;
lasciando un margine di alcuni pixel di variazione, recuperiamo il valore di top principale e lo sommiamo ai
valori dell'array seq visto in precedenza, se i valori di left rientrano nel margine di variazione della somma effettuata
(rispettando la sequenza di seq) si otterrà il messaggio di test superato, altrimenti gli oggetti verranno riposizionati ed il
messaggio sarà negativo.
if(((parseInt(liv_t[i].left)< (350+seq[i])) || (parseInt(liv_t[i].left)>(360+seq[i])))){
vt=1;
}
if(vt==1){
liv_t[i].top=20+(i*150)
liv_t[i].left=50
}
}
if(vt==1)alert('test errato!!')
else if(vt==0)alert('test superato!');
vt=0;
}
onload=crea_div;
</script>
</head>
<body >
<div id="princ"></div>
</body>
</html>
Nella pagina successiva di prova, prendere con il mouse le parti di bandiera italiana e trascinarle nel riquadro di destra. Rispettando o meno la sequenza corretta, si otterrà il risultato.
E' possibile ampliare a realizzare più test diversi con il metodo qui descritto.