Code du drag and drop des calques qui suivent la souris (fonctionne dans Netscape 4, 6 et 7, Internet Explorer, Mozilla 1.0, Opéra 5). Le script de "drag and drop" provient de la page de Stephen Koch : http://www.dpunkt.de/javascript/bsp/script2/dragdrop/index.html
Pour prendre en compte ces différents navigateurs, chaque fonction est écrite pour 3 cas :
if (document.layers) { ...} // cas de Netscape 4
else { if (document.all) {...} // cas d'Internet Explorer
else {if (document.getElementById) {...} // cas de Netscape 6-7 et Mozilla


<html>
<head>

<meta name="description" content="exercice de classement des métiers dans les catégories socio-profesionnelles (CSP)">
<meta name="keywords" content="CSP, métiers, drag and drop">
<meta name="Author" content=" Isabelle Gautier">
<title>Classement de m&eacute;tiers dans les cat&eacute;gories socio-professionnelles</title>

<script language="JavaScript">
<!--
// script réalisé par Isabelle Gautier
// le drag and drop provient de Stephen Koch sur http://www.dpunkt.de
var nbrediv = 12; // important à modifier si on ajoute des div
var dx = 0, dy = 0, current = null;
rep=new Array(12);
for (i=0; i<12; i ++) rep[i]=0
var score = 0, scoreneg = 0;
// solutions [numéro de l'objet], réponse 1 : 1er cadre, 2: en haut à //gauche, 3: en bas à gauche, 4 : en bas à droite
sol=new Array(12);
sol[0]=6; sol[1]=2; sol[2]=3; sol[3]=4; sol[4]=6; sol[5]=3; sol[6]=3; sol[7]=4; sol[8]=6; sol[9]=1; sol[10]=4; sol[11]=3;
// positions initiales des calques de métiers
ht=new Array (12);
ht[0]=104; ht[1]=104; ht[2]=150; ht[3]=150; ht[4]=198; ht[5]=198; ht[6]=245; ht[7]=245; ht[8]=293; ht[9]=293; ht[10]=340;ht[11]=340;
gau = new Array (12);
gau[0]=320; gau[1]= 500; gau[2]= 320; gau[3]=500; gau[4]=320; gau[5]=500; gau[6]=320; gau[7]=500; gau[8]=320; gau[9]=500; gau[10]=320; gau[11]=500;
var num = 0; var hauteur = 0; var gauche = 0;

if (!document.all && document.getElementById) alert("Prenez les étiquettes par les coins pour les déplacer")

function init() { // démarrage appelé dans la ligne body
// capture d'événènements pour Netscape 4
if (document.captureEvents) {
document.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP);
}

document.onmousedown = startDrag;
document.onmouseup = endDrag;
}

function startDrag(e) { // démarrage du suivi de la souris quand la souris est enfoncée
// recherche du DIV sur lequel il a été appuyé
num = -1; // initialisation de num = n° du calque déplacé
var found = false;
var i = nbrediv;

if (document.layers) { // cas de netscape 4
var zIndexGefunden = 0;
var gefunden = "";

while (i > 0) {
i--;
name="Layer"+i;
// position de l'objet sur lequel il est cliqué
if ((e.pageX > document.layers[name].left) &&
(e.pageX < document.layers[name].left + document.layers[name].clip.width) &&
(e.pageY > document.layers[name].top) &&
(e.pageY < document.layers[name].top + document.layers[name].clip.height)) {

if (document.layers[name].zIndex > zIndexGefunden) {
found = true;
gefunden = name;
num = i;
zIndexGefunden = document.layers[name].zIndex;
}
}
}

if (found) {
current = document.layers[gefunden];
dx = e.pageX - current.left;
dy = e.pageY - current.top;

// capture des évènements
document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = drag;
return false;
}
}
else { if (document.all) { // cas d'Internet Explorer
var obj = window.event.srcElement; // div sur lequel il a été appuyé
if ((obj.parentElement != null) &&
(obj.parentElement.id.indexOf("Layer") != -1)) {
current = obj.parentElement.style;
num = obj.parentElement.id.slice(5,7);
dx = window.event.clientX - current.pixelLeft;
dy = window.event.clientY - current.pixelTop;

document.onmousemove = drag;
return false;
}}
else {if (document.getElementById) { // Netscape 6 et Mozilla
var obj = e.target;
if ((obj.parentNode.id != null) &&
(obj.parentNode.id.indexOf("Layer") != -1)) {
current = obj.parentNode.style;
num = obj.parentNode.id.slice(5,7);
dx = e.clientX - parseInt(current.left);
dy = e.clientY - parseInt(current.top);

document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = drag;
return false;
}}
}
}
// au début il n'y a pas d'objet sélectionné
current = null;
return false;
}


function drag(e) { // déplacement du calque sélectionné
if (current != null && num < nbrediv) {
if (document.layers) { // cas de Netscape 4
current.top = e.pageY - dy;
current.left = e.pageX - dx;
hauteur = current.top;
gauche = current.left;
}
else {if (document.all) { // cas d'internet Explorer
current.pixelTop = window.event.clientY - dy;
current.pixelLeft = window.event.clientX - dx;
hauteur = current.pixelTop;
gauche = current.pixelLeft;
}
else {if (document.getElementById) { //IE5 ou Netscape 6
current.top = parseInt(e.clientY) - dy;
current.left = parseInt(e.clientX) - dx;
hauteur = current.top.substr(0,current.top.length - 2);
gauche = current.left.substr(0,current.left.length - 2);
}}
}
}

return false;
}

function endDrag(e) { // fin du déplacement
if (!document.all) { // netscape 4 et 6, Mozilla
document.releaseEvents(Event.MOUSEMOVE);
}
if (hauteur>78 && hauteur<120 && gauche>40 && gauche<222){ rep[num]=1 }
else if (hauteur>130 && hauteur<172 && gauche>40 && gauche<222){ rep[num]=2 }
else if (hauteur>182 && hauteur<224 && gauche>40 && gauche<222){ rep[num]=3 }
else if (hauteur>234 && hauteur<276 && gauche>40 && gauche<222){ rep[num]=4 }
else if (hauteur>286 && hauteur<328 && gauche>40 && gauche<222){ rep[num]=5 }
else if (hauteur>338 && hauteur<380 && gauche>40 && gauche<222){ rep[num]=6 }
else rep[num] = -1

if (num > -1) {
name = "Layer"+num;
if (num<12 && rep[num]==sol[num]) { // cas de la réponse juste : score + 1, calque s'efface
fscore();
// le calque devient invisible
if (document.layers) { //NS4.X seul
document.layers[name].visibility="hidde"
}
else if (document.all) { // IE
document.all[name].style.visibility = "hidden";
}
else if (document.getElementById) { // Netscape 6 , Mozilla
document.getElementById(name).style.visibility ="hidden";
}

}
else {
// si faux score = -1 , le calque revient à sa position initiale
if(num<12){
scoreneg --; fscore();
if (document.layers){ //NS4.X seul
document.layers[name].top = ht[num];
document.layers[name].left = gau[num];
}
else if (document.all) { // IE
document.all[name].style.top = ht[num];
document.all[name].style.left = gau[num];
}
else if (document.getElementById) { // Netscape 6 , Mozilla
document.getElementById(name).style.top = ht[num];
document.getElementById(name).style.left = gau[num];
}}}
}
document.onmousemove = null;
current = null;
return false;
}

function fscore(){
score = 0;
for (i=0; i<nbrediv; i++) {
if (rep[i] == sol[i]) score ++;
}
score = score + scoreneg;
document.form1.b1.value = "score="+ score + "/12";
}
// -->
</script>

</head>

<body onload="init()" bgcolor="#FFFFFF">
<p><b class="titre">CLASSEMENT DANS LES Cat&eacute;gories Socio-Professionnelles
<br>
</b><i>Classez les m&eacute;tiers cit&eacute;s &agrave; gauche de la page dans leur CSP. Pour cela, d&eacute;placez les &eacute;tiquettes jaunes en gardant le bouton gauche de la souris appuy&eacute;. Le m&eacute;tier dispara&icirc;t s'il a &eacute;t&eacute; plac&eacute; &agrave; la bonne place. Une erreur = -1 point.</i> </p>
<form name="form1" method="post" action="">
<div align="right">
<input type="button" name="b1" value="score ? " onClick="javascript:fscore()">
</div>
</form>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div id="Layer0" style="position:absolute; width:156;height:35;color:#0000FF;border-style:solid;border-width:1;border-color:#FFFF00;font-family:Arial;font-size:12px; visibility:visible; left: 320px; top: 104px; z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000">
<div align="center">salari&eacute; agricole </div>
</div>
<div id="Layer1" style="position:absolute; width:156;height:35;color:#0000FF;border-style:solid;border-width:1;border-color:#FFFF00;font-family:Arial;font-size:12px; visibility:visible; left: 500px; top: 102px; z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000">
<div align="center">plombier ind&eacute;pendant</div>
</div>
<div id="Layer2" style="position:absolute; width:156px; height:35px;color:#0000FF; z-index:2; left: 320px; top: 150px; visibility: visible;z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">professeur de mat&eacute;matiques</div>
</div>
<div id="Layer3" style="position:absolute; width:156px; height:35px; z-index:2; left: 500px; top: 151px; visibility:visible;color:#0000FF;z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">conducteur de train</div>
</div>
<div id="Layer4" style="position:absolute; width:156px; height:35px; z-index:2; left: 320px; top: 198px; visibility: visible;color:#0000FF; z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">ouvrier &agrave; la cha&icirc;ne</div>
</div>
<div id="Layer5" style="position:absolute; width:156px; height:35px; z-index:2; left: 500px; top: 199px; visibility: visible;color:#0000FF; z-index: 2; background: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">journaliste ind&eacute;pendant</div>
</div>
<div id="Layer6" style="position:absolute; width:156px; height:35px; z-index:2; left: 320px; top: 245px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">m&eacute;decin lib&eacute;ral</div>
</div>
<div id="Layer7" style="position:absolute; width:156px; height:35px; z-index:2; left: 500px; top: 246px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">technicien informatique</div>
</div>
<div id="Layer8" style="position:absolute; width:156px; height:35px; z-index:2; left: 320px; top: 294px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">chauffeur de bus</div>
</div>
<div id="Layer9" style="position:absolute; width:156px; height:35px; z-index:2; left: 500px; top: 293px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">&eacute;leveur de moutons</div>
</div>
<div id="Layer10" style="position:absolute; width:156px; height:35px; z-index:2; left: 320px; top: 341px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">infirmi&egrave;re </div>
</div>
<div id="Layer11" style="position:absolute; width:156px; height:35px; z-index:2; left: 500px; top: 339px; visibility: visible;color:#0000FF; background-color: #FFFFCC; layer-background-color: #FFFFCC; border: 1px none #000000; font-family:Arial; font-size:12px">
<div align="center">clown</div>
</div>
<br>
<div id="Layer21" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 39px; top: 78px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Agriculteurs exploitants</div>
</td>
</tr>
</table>
</div>
<div id="Layer22" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 40px; top: 130px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Artisans, commer&ccedil;ants, chefs d'entreprises</div>
</td>
</tr>
</table>
</div>
<div id="Layer23" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 40px; top: 182px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Cadres et professions intellectuelles sup&eacute;rieures</div>
</td>
</tr>
</table>
</div>
<div id="Layer24" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 40px; top: 234px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Professions interm&eacute;diaires</div>
</td>
</tr>
</table>
</div>
<div id="Layer25" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 40px; top: 286px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Employ&eacute;s</div>
</td>
</tr>
</table>
</div>
<div id="Layer26" class="calq" style="position:absolute; width:222px; height:42px; z-index:1; left: 40px; top: 338px; visibility: visible">
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">
<div align="center">Ouvriers</div>
</td>
</tr>
</table>
</div>

<BR>
<i>Avec Internet Explorer les &eacute;tiquettes se d&eacute;placent mieux en prenant
le mot, avec Netscape le coin.</i>
</body>
</html>

Explications:
<html>début de page
<head> début de "tête"
<TITLE>titre de la page</TITLE>
les métas donnent des indications
- name="Keybords" est important pour que les moteurs de recherche retrouvent votre page
- name="Author" précise qui a créé la page



<script ... : début du script.
<-- indique aux vieux navigateurs qu'il ne faut pas afficher ce qui suit
// tout ce qui est dans une ligne qui commence par deux barres est un commentaire

annonce des différentes variables, une variable peut être définie en écrivant "var" son nom et éventuellement sa valeur (ici : nbrediv est égal à 12). L'annonce de plusieurs variables peut se faire sur la même ligne sans réécrire var si on les sépare par une virgule.
rep[i] notera les différentes réponses : le numéro du calque fixe sur lequel le calque déplaçable a été mis.
sol[i] est la solution
ht[i] la hauteur de départ du calque à partir du haut de la fenêtre du navigateur
gau[i] la position de départ du calque à partir du bord gauche de la fenêtre.

 

 

 

si le navigateur est Netscape 6-7 ou Mozilla, un message d'alerte précise que les calques se "prennent" par un coin. if (condition) alert
La condition est que "document.all" ne soit pas possible : "!document.all" : seul internet explorer accepte document.all. && = "et"
document.getElementById est compris par Netscape 6-7 et Mozilla (mais aussi par IE, c'est pourquoi nous l'avons éliminé)

La fonction init : function init(){...} est appelée dans la ligne Body donc à tout moment. Pour Netscape 4 "if(document.captureEvents)" il faut capturer l'évènement "souris enfoncée" (Event.MOUSEDOWN) ou ( | ) "souris relevée" (Event.MOUSEUP)
Pour tous les navigateurs si la souris est enfoncée, la fonction startDrag commence, si la souris en relevée, la fonction endDrag est appelée.

La fonction startDrag : fait suivre la souris au calque sur lequel il a été appuyé
Il faut donc débord rechercher le calque (DIV):
initialisation des variables : num qui sera le numéro du calque est mis à -1 (les calques sont numérotés de 0 à 12); la variable found est mise à "faux" (elle sera "vraie" quand un calque aura été cliqué); i est le nombre de calques déplaçables (ici 12)
- pour Netscape if (document.layers) { : e.pageX donne les coordonnées de la souris.
On teste while (i > 0) tant que i est supérieur à 0, si les coordonnées correspondent aux coordonnées d'un layer (nom des DIV pour Netscape), les variables found = vrai, gefunden = le nom du Layer, i est gardé dans la variable num.

 

 

 

 

 

if (found) : si la variable found est vraie, donc si un Layer a été cliqué, les variables current, dx, dy conservent l'objet (document.layers[gefunden]) et l'écart entre la position de la souris et celle du layer.

il faut de nouveau capturer l'évènement et si la souris a bougé aller à la fonction drag.

 

else : si ce n'est pas Netscape 4,
if (document.all) : si c'est Internet Explorer
on utilise la variablbe obj , IE permettant de connaître directement l'objet surlequel il a été appuyé grâce à window.event.srcElement : window est la page, event : l'événement de la souris, srcElement : la référence de l'objet
if si obj.parentElement != null l'élément parent de obj n'est pas null && et si obj.parentElement.id.indexOf("Layer") != -1le numéro du Layer (tous les calques s'appellent "Layer"+ un numéro) parent de l'objet n'est pas -1 (on a initialisé à -1 tout à l'heure la variable num) , il a bient été clqiué sur un calque et on retient non num, dx et dy.

else {if (document.getElementById) { si ce n'est ni Netscape 4, ni IE, et que le navigateur prend en compte "getElementById", c'est Netscape 6-7 ou Mozilla
L'objet surlequel il a été cliqué se trouve grâce à e.target
Comme tout à l'heure, mais avec "parentNode.id" c'est un calque déplaçable si l'objet parent n'est pas null et son numéro différent de -1.
Un nouvel événement est capturé et si la souris a bougé, la fonction drag est appelée.

 

 


La variables current est mise à null, si aucun objet n'est sélectionné.

 


la fonction drag : déplace le calque
si current n'est pas null et si num < nbrediv si le numéro du calque est inférieur au nombre total de calques déplaçables (ceci évite dans les pages où il y a des calques avec des flèches que celles-ci soient déplacées).
Pour Netscape 4, les positions de l'objet s'appellent current.top et current.left (current est notre variable : l'objet qui bouge). Les positions de la souris sont e.pageY et e.pageX
hauteur
et gauche gardent en mémoire la position de la souris pour pouvoir tester dans la fonction suivante si c'est au bon endroit que le calque a été placé.

alors que pour Internet Explorer c'est current.pixelTop et current.pixelLeft . La position de la souris est trouvée par window.event.clientY et window.event.clientX

pour Netscape 6-7 et Mozilla c'est current.top et current.left comme Netscape 4 mais la position de la souris est la partie entière de e.clinetY : parseInt(e.clientY) et parseInt(e.clientX)

 

 

 

de nouveau si current est null, found est remis à faux.

function endDrag : fin du déplacement
s'il ne s'agit pas d'Internet Explore, il faut vider l'événement. document.releaseEvents(Event.MOUSEMOVE)

La position de la souris au moment où elle a été relâchée a été conservée dans les variables hauteur et gauche, elles sont comparées aux positions des calques fixes. Si la position correspond au calque fixe 1, la réponse rep[num] sera 1. Num est le numéro du calque déplacé.

 

 


else rep[num] = -1 si la position ne correspond pas à un calque fixe, la réponse est -1

if (num > -1) { si un calque a été déplacé
son name nom sera "Layer" plus son numéro
if (num<12 si le calque déplacé correspond à un calque déplaçable
&& rep[num]==sol[num])
et si la réponse est juste,
fscore() la fonction qui affiche le score est appelée
et la visibilité des calques devient "invisible" (à noter les écritures différentes selon les navigateurs)

 

 

 

else : sinon si la réponse est fausse,
if(num<12) si le calque est toujours un calque déplaçable,
il est retiré un point : la varaible scoreneg est diminuée d'un point, elle retient les erreurs,
et la fonction fscore est appelée
le calque retourne à sa place d'origine.
Pour Netscape, c'est "document.layers[name]"
pour Internet Explorer "document.all[name].style"
et pour Netscape 6 et Mozilla "document.getElementById(name).style"

 

 

 

 

remise à zéro des variables

 

la fonction fscore calcule le score : elle teste si les réponses sont égales aux solutions. ajoute 1 point par calque bien placé à la variable score et y ajoute scoreneg à laquelle on a retiré un point par erreur.
Le score est affiché dans le bouton b1 du formulaire form1 , value est ce qui est indiqué sur le bouton, donc en javascript : document.form1.b1.value = score

 

le body inclut l'appel à la fonction init

 

les consignes

 

 

le formulaire

le bouton qui affiche le score : il appelle la fonction fscore si l'on clique dessus : onClick="javascript:fscore()"(mais le score est aussi affiché dès qu'un calque est placé car dans Netscape 6-7 et Mozilla le script précédent annule les possibilités d'action sur les boutons).

 

Les calques déplaçables s'appellent tous <div id ="Layer0"
style=" ..."> définit leurs caractéristiques.
<div align="center"> pour que le texte soit centré
</div> fin du centrage
</div> fin du div

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pour pourvoir être déplacé, un div ne doit pas contenir de tableau. C'est pourquoi les calques fixes en contiennent :
<table width="222" border="1" bgcolor="#FFFFCC" height="42">
<tr bgcolor="#e7e7e7" bordercolor="1">
<td height="42" bgcolor="#ffe6e6">

un tableau avec un seule colonne et une seule ligne.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Fin du body et de la page html


début des pages sur les calques
retour au sommaire


Réalisé par Isabelle Gautier, la diffusion de cet article est protégée par la licence LLDL-v1, Licence de Libre Diffusion des Documents, http://pauillac.inria.fr/~lang/licence/v1/lldd.html . Vous pouvez libremet utiliser, modifier et diffuser ce document mais uniquement à titre gratuit.