Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site
Un "drag and drop" consiste à déplacer un élément d'une zone source vers une zone destination avec la souris.
Il peut être intéressant d'introduire cet fonctionnalité dans une page web.
HTML 5 propose désormais une API "glisser-déposer".
Il faut rappeler que framework Jquery proposait déjà des méthodes pour réaliser facilement un "drag & drop".
Pendant longtemps la seule solution pour programmer un "drag and drop" dans une page web était d'utiliser le célèbre framework jQuery et plus précisément son extension : jQuery-UI.
Ci-dessous un document HTML avec des images transférables d'un conteneur vers un autre :
Vous pouvez déplacer les images de la boite du haut vers la boite du bas (fond rose) et vice-versa.
Partie HEAD : il faut charger deux fichiers .js (celui de la librairie jQuery et celui de l'extension jQuery UI).
CSS : Les images sont des éléments inline-block
HTML : Les images sont dans le conteneur "source" et le conteneur "destination" est initialement vide.
Le script :
Il est d'une simplicité déroutante.
La première méthode rend "glissable" les éléments référencés (donc ici les images).
La deuxième méthode rend "déposable" les éléments référencés (ici les DIV).
Donc on pourra faire glisser les images de la boite "source" vers la boite "destination" et vice-versa.
Désormais avec l'API web "glisser-déposer" il est possible de programmer un 'drag and drop' sans recourir à jQuery.
Ci-dessous un document HTML avec des images transférables :
Vous pouvez déplacer les images de la boite du haut vers la boite du bas mais pas l'inverse.
Dans la partie HEAD les d'instructions pour charger les librairies de jQuery ont disparu.
Pour être transférables par la souris d'un conteneur vers un autre, les éléments doivent avoir l'attribut draggable ='true' et avoir un ID. En effet l'élément déplacé est référencé par son ID.
Pour un drag & drop unilatéral (de la zone "source" vers la zone "destination") il faut associer l'événement "ondragStart" à la zone source et les deux autres événements à la zone destination.
À chaque événement est associé une fonction.
function debut(e) // associé à dragstart { e.dataTransfer.effectAllowed ="move"; e.dataTransfer.setData('text',e.target.getAttribute('id')); } function glisser(e) {e.preventDefault(); } // associé à dragover function deposer(e) //associé à drop { objet = e.dataTransfer.getData('text'); e.currentTarget.appendChild(document.getElementById(objet)); e.stopPropagation; }
Pour transférer les données d'une zone source vers une zone destination il faut utiliser l'objet dataTransfer.
Cet objet comprend deux méthodes setData() & getData().
La methode setData() permet de mémoriser les données à déposer. Elle comprend deux paramètres : le premier est "text" et
le deuxième précise le type de donnée à déposer.
La méthode getData() permet de récupérer les données mémorisées par la méthode précédente et ne comprend
qu'un argument : "text".
Fonction debut(e) : récupération de l'ID de l'élément sélectionnée via l'instruction
e.dataTransfer.setData('text',e.target.getAttribute('id'))
Fonction glisser(e) : par défaut le navigateur interdit de déposer un élément à l'intérieur d'un autre conteneur.
Pour autoriser un dépôt, nous devons empêcher la gestion par défaut du navigateur avec l'instruction e.preventDefault()
Fonction deposer(e) : ajout de l'élément transféré au conteneur "destination" via l'instruction
e.currentTarget.appendChild(document.getElementById(objet))
Dans l'exemple précédent, on peut transférer une image du conteneur "source" vers le conteneur "destination" mais par l'inverse. C'est facheux si on s'est trompé et que l'on veuille annuler un mauvais choix.
Pour un drag & drop bilatéral il suffit d'associer les trois événements aux deux conteneurs.
Ci-dessous un document HTML dans lequel les images sont transférables dans les deux sens.
Le script ne change pas ! Il suffit d'associer les trois évènements aux conteneurs source et destination ; il suffit donc de modifier le code de la partie BODY.
Les événements sont insensibles à la "casse". Vous pouvez écrire "onDragStart" ou "ondragstart" , "onDragOver" ou "ondragover", "onDrop" ou "ondrop".
Ci-dessous un document HTML avec des images dans un conteneur.
Il n'y a pas de conteneur "destination" mais il y a un bouton de commmande ...
Cliquez sur le bouton de commande !
Notez l'ajout d'une nouvelle boite et la disparition du bouton de commande.
Tentez de déplacer les images d'un conteneur vers un autre.
Je vous invite aussi à lire l'onglet "éléments" de la console pour voir
tout le code HTML généré par le script.
Notez l'absence d'attribut ID et draggable pour les images.
function ajout() { var destination = document.createElement('div'); destination.setAttribute("id", "destination"); destination.setAttribute("class","boite"); document.querySelector('body').appendChild(destination); var images = document.querySelectorAll('img') ; var source = document.getElementById('source'); var destination = document.getElementById('destination'); // affectation de deux attributs à chaque image for (var i =0 ; i < images.length ; i++) { images[i].setAttribute("id", "img" + i); images[i].setAttribute("draggable",true); // instructions provisoires console.log(images[i].getAttribute('id')); console.log(images[i].getAttribute('draggable')); } // gestion des événements source.addEventListener('dragstart', debut); source.addEventListener('dragover', glisser); source.addEventListener('drop', deposer); destination.addEventListener('dragstart', debut); destination.addEventListener('dragover', glisser); destination.addEventListener('drop', deposer); // fonction associée à dragstart function debut(e) { e.dataTransfer.effectAllowed ="move"; e.dataTransfer.setData('text',e.target.getAttribute('id')); } // fonction associée à dragover function glisser(e) {e.preventDefault(); } // fonction associée à drop function deposer(e) { objet = e.dataTransfer.getData('text'); e.currentTarget.appendChild(document.getElementById(objet)); e.stopPropagation; } document.querySelector('button').remove(); } // fin ajout
Dans une premier temps le script crée un nouveau DIV avec certains attributs.
Cette boite est insérée à la fin de BODY.
Puis le script crée de nouveaux attributs pour les images (ID et draggable).
Ensuite gestion des six événements (trois par conteneur) avec utilisation de la méthode addEventListener()
Attention à la syntaxe dans le cadre de cette méthode ; les événements sont entre quotes et ne sont plus préfixés "on".
Il suffit de rajouter ce script à une page web pour que les images de celle-ci deviennent transférables d'un conteneur
vers un autre.
Il est préférable d'externaliser ce script. J'ai donc mis le code dans une fichier nommée "ajout.js" ;
ce script se lance automatiquement car j'ai rajouté l'instruction ajout(); // appel de la fonction ajout().
Récupération de ce fichier
Notez l'instruction qui charge le fichier "ajout.js".
Ouvrez cette page web avec un navigateur.
Observez l'ajout d'un nouveau conteneur.
Vous pouvez faire des drag & drop bilatéraux.