Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
La manière de procéder en elle-même n'est pas difficile à comprendre.
À chaque réalisation de l'évènement
mousemove, nous allons appeler une fonction dans le
body, c'est-à-dire à chaque fois que le curseur de la souris change de position.
Si une fenêtre est en cours de déplacement, la fonction se chargera de la positionner en fonction de la position du curseur.
Mais comment cette fonction peut-elle savoir si une fenêtre est en cours de déplacement ?
Nous voulons donc que notre fonction puisse savoir si une fenêtre est en cours de déplacement, et laquelle.
Vous l'aurez deviné, nous allons créer une autre variable globale !
Code : JavaScript
Cette variable aura pour but de dire quelle fenêtre est en cours de déplacement. Elle vaudra donc 0 si aucune fenêtre n'est en déplacement et pointera sur une fenêtre si celle-ci est en déplacement.
À quels moments faut-il modifier la valeur de cette variable ?
Vous êtes d'accord avec moi : le déplacement d'une fenêtre commence lorsque l'on enfonce le bouton de la souris sur la barre de titre de la fenêtre, et s'arrête lorsqu'on relâche le bouton.
Pour modifier le contenu de notre variable globale selon qu'une fenêtre est déplacée ou non, il nous suffit de modifier son contenu en appelant une fonction lors de la réalisation des événements
mousedown et
mouseup sur la
div de
class haut de notre fenêtre :
Tout d'abord, les fonctions pour modifier le contenu de notre variable :
Code : JavaScript1
2
3
4
5
6 | function commencer_deplacement(fenetre) {
fenetre_deplacee=fenetre; //la variable pointe désormais sur la fenêtre à déplacer
}
function arreter_deplacement() {
fenetre_deplacee=0; //La variable vaut 0
}
|
Maintenant, ajoutons les événements
mousedown et
mouseup à la barre de titre de nos fenêtres (la
div haut) dans notre fonction
creer_fenetre :
Code : JavaScript 1
2
3
4
5
6
7
8
9
10
11
12
13 | //On les rajoute à la div "haut", donc juste après l'avoir créée
var haut = document.createElement("div");
haut.className="haut";
//Pour mousedown
if(document.all) haut.attachEvent("onmousedown",function (){commencer_deplacement(fenetre)});
else haut.addEventListener("mousedown",function (){commencer_deplacement(fenetre)},true);
//Et pour mouseup
if(document.all) haut.attachEvent("onmouseup",arreter_deplacement);
else haut.addEventListener("mouseup",arreter_deplacement,true);
//etc.
|
Vous ne trouvez pas que c'est un peu lourd de recopier
if(document.all) ... à chaque fois ?
Je vous propose de simplifier tout ça en créant une fonction pour rajouter un événement (auteur: Boo2M0rs0) :
Code : JavaScript1
2
3
4
5
6 | function addEvent(obj,event,fct){
if(obj.attachEvent)
obj.attachEvent('on' + event,fct);
else
obj.addEventListener(event,fct,true);
}
|
Ainsi, on n'a plus qu'à faire cela :
Code : JavaScript1
2
3
4
5
6
7
8 | //On les rajoute à la div "haut", donc juste après l'avoir créé
var haut = document.createElement("div");
haut.className="haut";
addEvent(haut,"mousedown",function (){commencer_deplacement(fenetre)});
addEvent(haut,"mouseup",arreter_deplacement);
//etc.
|
Voilà : maintenant, quand une fenêtre est en cours de déplacement, c'est-à-dire quand on a enfoncé le bouton de la souris sur la barre de titre de la fenêtre sans le relâcher,
fenetre_deplacee indiquera la fenêtre en cours de déplacement.
Et maintenant, le contenu complet de notre fichier Javascript :
Code : JavaScript 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 | var zindex=0;
var fenetre_deplacee=0;
function creer_fenetre(left,top,width,height) {
var fenetre = document.createElement("div");
fenetre.className="fenetre"; //On donne un attribut class à cette div
fenetre.style.left=left+"px"; //Modification de l'attribut left du style de notre div
fenetre.style.top=top+"px";
fenetre.style.width=width+"px";
fenetre.style.height=height+"px";
addEvent(fenetre,"mousedown",function (){premier_plan(fenetre)});
//On crée de la même manière la div "haut" :
var haut = document.createElement("div");
haut.className="haut";
addEvent(haut,"mousedown",function (){commencer_deplacement(fenetre)});
addEvent(haut,"mouseup",arreter_deplacement);
//On crée ensuite les trois div qui y figureront :
var haut_gauche = document.createElement("div");
haut_gauche.className="haut_gauche";
var haut_droite = document.createElement("div");
haut_droite.className="haut_droite";
var haut_centre = document.createElement("div");
haut_centre.className="haut_centre";
//Puis on les insère une par une dans notre bloc "haut" :
haut.appendChild(haut_gauche);
haut.appendChild(haut_droite);
haut.appendChild(haut_centre);
//On insère le tout (la div "haut" et les trois div à l'intérieur) dans le bloc "fenetre" :
fenetre.appendChild(haut);
//On fait de même pour la div "milieu"
var milieu = document.createElement("div");
milieu.className="milieu";
var milieu_gauche = document.createElement("div");
milieu_gauche.className="milieu_gauche";
var milieu_droite = document.createElement("div");
milieu_droite.className="milieu_droite";
var milieu_centre = document.createElement("div");
milieu_centre.className="milieu_centre";
milieu.appendChild(milieu_gauche);
milieu.appendChild(milieu_droite);
milieu.appendChild(milieu_centre);
fenetre.appendChild(milieu);
//On fait de même pour la div "bas"
var bas = document.createElement("div");
bas.className="bas";
var bas_gauche = document.createElement("div");
bas_gauche.className="bas_gauche";
var bas_droite = document.createElement("div");
bas_droite.className="bas_droite";
var bas_centre = document.createElement("div");
bas_centre.className="bas_centre";
bas.appendChild(bas_gauche);
bas.appendChild(bas_droite);
bas.appendChild(bas_centre);
fenetre.appendChild(bas);
premier_plan(fenetre); //On met au premier plan notre fenêtre
document.body.appendChild(fenetre); //On insère le tout dans notre document, dans le corps
}
function premier_plan(fenetre) {
zindex++; //On incrémente la variable globale
fenetre.style.zIndex=zindex; //On affecte sa valeur au z-index de la fenêtre concernée
}
function commencer_deplacement(fenetre) {
fenetre_deplacee=fenetre; //la variable pointe désormais sur la fenêtre à déplacer
}
function arreter_deplacement() {
fenetre_deplacee=0; //La variable vaut 0
}
function addEvent(obj,event,fct){
if(obj.attachEvent)
obj.attachEvent('on' + event,fct);
else
obj.addEventListener(event,fct,true);
}
|
Maintenant que nous pouvons savoir si une fenêtre est en cours de déplacement, nous allons créer la fonction qui, à chaque mouvement de souris, c'est-à-dire lors de l'événement
mousemove du
body, positionnera la fenêtre concernée en fonction de la position du curseur.
Tout d'abord, appelons notre fonction lors de l'évènement
mousemove :
Code : HTML1 | <body onmousemove="deplacer_fenetre(event)">
|
Pourquoi ai-je rajouté un argument event à la fonction ?
event est une variable qui, à chaque fois qu'un événement se produit, nous donne diverses informations relatives à celui-ci. Dans notre cas, elle va nous permettre de récupérer la position du curseur.
Écrivons maintenant notre fonction :
Code : JavaScript1
2
3
4
5
6
7
8
9 | function deplacer_fenetre(ev) {
if(fenetre_deplacee!=0) { //On effectue le déplacement que s'il y a une fenêtre à déplacer
var souris=mouseCoords(ev); //On récupère les coordonnées de la souris
fenetre_deplacee.style.left=souris.x+'px'; //On affecte à notre fenêtre sa nouvelle position : celle du curseur
fenetre_deplacee.style.top=souris.y+'px';
}
}
|
Voilà maintenant le code de notre fonction qui récupère les coordonnées de la souris :
Code : JavaScript1
2
3
4
5
6
7
8
9 | function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop - document.body.clientTop
};
}
|
Il n'est pas nécessaire de savoir ce qu'elle fait en détail. Sachez juste que cette fonction renvoie un objet avec deux propriétés : x et y, indiquant l'abscisse et l'ordonnée du curseur.
Notre fonction, qui est appelée à chaque mouvement du curseur, met la fenêtre à la position de celui-ci, si celle-ci est en cours de déplacement.
Actualisez, ouvrez une fenêtre et essayez de la déplacer.
Notre fenêtre se déplace bien avec le curseur, mais le coin gauche de celle-ci s'est positionné au niveau du curseur.
C'est dû au fait que nous n'avons pas pris en compte la position du curseur dans la barre de titre de la fenêtre.
Comment faire ?
Vous vous en doutez : il faut, lorsque la fenêtre commence à être déplacée, c'est-à-dire lors de l'appel de la fonction
commencer_deplacement, enregistrer dans deux autres variables globales l'abscisse et l'ordonnée du curseur par rapport au coin haut gauche de la fenêtre :
Ensuite, lors de l'appel de la fonction
deplacer_fenetre, on n'aura plus qu'à soustraire ces variables aux coordonnées de la souris.
Allons-y !
Créons nos deux variables globales :
Code : JavaScript1
2 | var fenetre_deplacee_difx=0;
var fenetre_deplacee_dify=0;
|
Modifions notre fonction
deplacer_fenetre :
Code : JavaScript1
2
3
4
5
6
7 | function deplacer_fenetre(ev) {
if(fenetre_deplacee!=0) {
var souris=mouseCoords(ev);
fenetre_deplacee.style.left=(souris.x-fenetre_deplacee_difx)+'px'; //On soustrait l'abscisse du curseur par rapport au coin gauche de la fenêtre
fenetre_deplacee.style.top=(souris.y-fenetre_deplacee_dify)+'px'; //On fait de même avec l'ordonnée
}
}
|
Puis modifions notre fonction
commencer_deplacement :
Code : JavaScript1
2
3
4
5
6
7
8 | function commencer_deplacement(ev,fenetre) {
fenetre_deplacee=fenetre; //On définit quelle fenêtre est en cours de déplacement
old_mouseCoords=mouseCoords(ev); //On récupère la position de la souris
old_windowCoords=getPosition(fenetre); //Et la position de notre fenêtre
//On stocke les différences dans les variables globales
fenetre_deplacee_difx=old_mouseCoords.x-old_windowCoords.x;
fenetre_deplacee_dify=old_mouseCoords.y-old_windowCoords.y;
}
|
Comme vous pouvez le constater, on est obligé de rajouter un argument, car on va avoir besoin de la variable
event.
Modifions en conséquence l'ajout de cette fonction lors de l'événement
mousedown sur notre bloc
haut :
Code : JavaScript1 | addEvent(haut,"mousedown",function (event){commencer_deplacement(event,fenetre)});
|
Vous avez vu : on récupère la position de notre fenêtre avec une fonction
getPosition().
Voilà cette fonction :
Code : JavaScript 1
2
3
4
5
6
7
8
9
10
11
12 | function getPosition(e){
var left = 0;
var top = 0;
while (e.offsetParent){
left += e.offsetLeft;
top += e.offsetTop;
e = e.offsetParent;
}
left += e.offsetLeft;
top += e.offsetTop;
return {x:left, y:top};
}
|
Cette fonction accueille un argument : l'élément dont on veut la position, et renvoie un objet identique à l'objet renvoyé par la fonction
mouseCoords(), informant sur la position de notre élément.
Si vous voulez comprendre cette fonction plus en détail, lisez le chapitre sur les coordonnées des blocs de B2Moo ici :
Les coordonnées des blocs.
Maintenant, à chaque fois que l'on commence le déplacement d'une fenêtre, les variables globales
fenetre_deplacee_difx et
fenetre_deplacee_dify prendront pour valeurs les coordonnées du curseur par rapport au coin haut gauche de la fenêtre. Ainsi, à chaque appel de la fonction
deplacer_fenetre, on garde sa position.
Actualisez, ouvrez une fenêtre puis déplacez-la...
Ça marche !