W3docs

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é que auto se repose simplement sur le comportement par défaut, il est rarement écrit explicitement ; omettre draggable produit le même résultat.
<tag draggable="true|false|auto"></tag>

Remarque : draggable n'est pas un attribut boolean. Vous devez écrire la valeur explicitement — draggable seul ou draggable="" est invalide. Utilisez toujours draggable="true" ou draggable="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énementSe déclenche surQuand
dragstartsourceL'utilisateur commence à glisser l'élément. Définissez vos données ici avec dataTransfer.setData().
dragsourceRépété tant que l'élément est en cours de glissement.
dragentercibleL'élément glissé entre dans une cible de dépôt valide.
dragovercibleRépété tant que l'élément est au-dessus d'une cible de dépôt. Appelez preventDefault() ici.
dragleavecibleL'élément glissé quitte la cible de dépôt.
dropcibleL'élément est relâché au-dessus de la cible. Lisez vos données ici avec dataTransfer.getData().
dragendsourceLe 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 du dragstart. Le format est 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 du drop.

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.

Exercice pratique

Pratique
Qu'est-ce qui est vrai concernant l'attribut HTML draggable ?
Qu'est-ce qui est vrai concernant l'attribut HTML draggable ?
Was this page helpful?