Attribut draggable HTML
L'attribut HTML draggable indique si un élément peut être glissé par l'utilisateur. Découvrez ses valeurs et les éléments sur lesquels il s'applique.
L'attribut HTML draggable est un attribut énuméré qui indique si un élément peut être glissé par l'utilisateur à l'aide d'un dispositif de pointage (souris ou tactile). Il constitue le point d'entrée de l'API HTML Drag and Drop, qui permet de déplacer des éléments, du texte, des fichiers ou des données personnalisées d'un endroit à un autre dans une page.
Définir draggable="true" rend uniquement un élément saisissable. Pour déplacer réellement quelque chose et le déposer à un endroit utile, vous devez également gérer les événements de glisser-déposer et transmettre des informations via l'objet dataTransfer — tous deux décrits ci-dessous.
Vous pouvez utiliser cet attribut sur n'importe quel élément HTML. Il fait partie des Attributs globaux et fonctionne donc aux côtés d'autres attributs globaux tels que contenteditable.
Valeurs
L'attribut draggable peut prendre les valeurs suivantes :
true— l'élément peut être glissé.false— l'élément ne peut pas être glissé. Utile pour désactiver le glissement par défaut des images et des liens.auto— utilise le comportement par défaut du navigateur pour cet élément. En pratique, cela signifie que les images et les liens sont déplaçables, et la plupart des autres éléments ne le sont pas. Étant donné queautose repose simplement sur le comportement par défaut, il est rarement écrit explicitement ; omettredraggableproduit le même résultat.
<tag draggable="true|false|auto"></tag>Remarque :
draggablen'est pas un attribut boolean. Vous devez écrire la valeur explicitement —draggableseul oudraggable=""est invalide. Utilisez toujoursdraggable="true"oudraggable="false".
Fonctionnement du glisser-déposer
Une interaction de glisser-déposer déclenche une séquence d'événements, répartis entre l'élément glissé (la source) et l'élément sur lequel il est déposé (la cible) :
| Événement | Se déclenche sur | Quand |
|---|---|---|
dragstart | source | L'utilisateur commence à glisser l'élément. Définissez vos données ici avec dataTransfer.setData(). |
drag | source | Répété tant que l'élément est en cours de glissement. |
dragenter | cible | L'élément glissé entre dans une cible de dépôt valide. |
dragover | cible | Répété tant que l'élément est au-dessus d'une cible de dépôt. Appelez preventDefault() ici. |
dragleave | cible | L'élément glissé quitte la cible de dépôt. |
drop | cible | L'élément est relâché au-dessus de la cible. Lisez vos données ici avec dataTransfer.getData(). |
dragend | source | Le glissement se termine (qu'il ait été déposé avec succès ou annulé). |
L'objet dataTransfer
Chaque événement de glissement expose event.dataTransfer, le canal utilisé pour transmettre des données de la source à la cible :
event.dataTransfer.setData(format, data)— stocke une string lors dudragstart. Leformatest généralement un type MIME tel que"text/plain"(l'ancien code utilise"Text", ce qui fonctionne encore).event.dataTransfer.getData(format)— récupère cette string lors dudrop.
Les données n'étant disponibles qu'au drop, le modèle typique consiste à stocker l'id d'un élément (ou tout autre identifiant) lors du dragstart, puis à le retrouver et à le déplacer lors du drop.
Pourquoi preventDefault() est nécessaire
Par défaut, la plupart des éléments ne sont pas des cibles de dépôt valides, ce qui amène le navigateur à annuler le dépôt. Pour qu'un élément serve de zone de dépôt, vous devez appeler event.preventDefault() dans son gestionnaire dragover — cela indique au navigateur que « oui, un dépôt est autorisé ici ». Il est également courant d'appeler preventDefault() dans le gestionnaire drop pour empêcher l'action par défaut du navigateur (par exemple, naviguer vers un lien glissé ou ouvrir un fichier déposé).
Si vous oubliez preventDefault() dans dragover, l'événement drop ne se déclenche jamais et rien ne se passe.
Exemple (gestionnaires en ligne)
Cet exemple utilise des attributs de gestionnaire d'événements en ligne (ondragstart, ondragover, ondrop). Il est concis, mais mélange JavaScript dans le balisage :
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#rectId {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(event) {
event.preventDefault(); // Allow dropping
}
function drag(event) {
// Store the dragged element's ID in the dataTransfer object
event.dataTransfer.setData("text/plain", event.target.id);
}
function drop(event) {
event.preventDefault();
var data = event.dataTransfer.getData("text/plain"); // Retrieve the ID
event.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<div id="rectId" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br />
<p id="dragId" draggable="true" ondragstart="drag(event)">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
</body>
</html>Exemple (avec addEventListener)
Pour un code maintenable, gardez le balisage propre et attachez les gestionnaires en JavaScript avec addEventListener. Il s'agit de l'approche recommandée :
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#dropzone {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<div id="dropzone"></div>
<br />
<p id="item" draggable="true">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
<script>
const item = document.getElementById("item");
const dropzone = document.getElementById("dropzone");
// Source: store the dragged element's ID when the drag begins.
item.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text/plain", event.target.id);
});
// Target: allow dropping by preventing the default handling.
dropzone.addEventListener("dragover", (event) => {
event.preventDefault();
});
// Target: move the element into the drop zone.
dropzone.addEventListener("drop", (event) => {
event.preventDefault();
const id = event.dataTransfer.getData("text/plain");
const dragged = document.getElementById(id);
event.currentTarget.appendChild(dragged);
});
</script>
</body>
</html>Accessibilité
L'attribut draggable ne fournit aucune prise en charge du clavier ni des lecteurs d'écran — le glisser-déposer est une interaction réservée aux dispositifs de pointage. Les utilisateurs qui naviguent au clavier ou avec des technologies d'assistance ne peuvent pas effectuer un glissement natif.
Si le glisser-déposer est le seul moyen d'accomplir une action, proposez toujours une alternative accessible (par exemple, des boutons « Monter / Descendre », un menu de sélection ou le copier-coller). Traitez le glisser-déposer natif comme une amélioration, pas comme le seul chemin.