En résumé (très court), c'est assez simple :

  • il faut indiquer l'attribut draggable="true" sur les éléments sur lesquels un drag'n'drop peut démarrer
  • des évènements sont envoyés sur l'élément à partir duquel le drag'n'drop a démarré : dragstart (au moment où on commence le drag), drag (plusieurs fois pendant le drag) et dragend (lorsque le drag est terminé)
  • sur les élements au dessus desquels la souris passe pendant le drag, on reçoit les évènements dragenter (on entre au dessus de l'élèment) et dragleave (on sort de l'élément). On reçoit aussi l'évènement dragover durant lequel on peut indiquer si oui ou non le drop est possible.
  • Enfin, lorsque l'utilisateur relache le bouton de la souris, l'élement qui est sous la souris reçoit l'évènement drop (si lors du dragover il a été indiqué que le drop est possible). C'est à ce moment là (ou sur l'évènement dragend reçu par l'élèment de départ) que l'on peut faire le traitement correspondant au drag'n'drop : par exemple, déplacer un element DOM, ou récupérer les informations stockées dans le dataTransfer et en faire ce que l'on veut...

Sur ces événements DOM, il y a une propriété dataTransfer qui peut contenir des données à "transférer", mais aussi le type de drag'n'drop (move, copy etc..).

Pour mieux comprendre comment ça fonctionne, j'ai crée un exemple simple, où vous pouvez glisser-déposer des petites boites dans d'autres plus grosses. Pour l'utiliser, il vous faut télécharger une nightly de Firefox 3.1. À noter qu'il faut cliquer une première fois sur une petite boite avant de faire le glisser-déposer proprement dit, comme si il fallait d'abord mettre le focus sur la boite. Je ne sais pas si c'est normal, si c'est un bug avec la version linux, ou si c'est mon code, mais pour le moment c'est comme ça :-/[1] [2]

Les avantages de cette API de drag'n'drop de HTML5 :

  1. bien sûr, ça sera normalisé, donc on pourra s'attendre à ce que ce soit le même fonctionnement sur les autres navigateurs
  2. c'est au moins aussi simple, voir plus simple que de manipuler les évènements de souris (quand on n'utilise pas une lib DHTML)
  3. on peut mieux distinguer dans l'application les mouvements de souris simple des mouvements de glisser-déposer.

Mais l'un des plus gros avantage, c'est que c'est du vrai drag'n'drop ! Par vrai, je veux dire qu'il fonctionne avec les autres applications : en théorie[3] vous pouvez faire un glisser-déposer à partir d'une page web vers un éditeur de texte, un lecteur de mail par exemple, ou un autre site web. Si vous indiquez des données au travers de la propriété dataTransfer, l'éditeur de texte les recevra tout naturellement. En fait le navigateur ne fait que réutiliser le mécanisme de drag'n'drop de votre système graphique. Et bien entendu, c'est valable dans l'autre sens : si vous glissez-déposez un morceau de texte à partir d'une application quelconque vers votre page web, celle-ci le recevra. À la page web de prendre en charge ce glissé-deposé.

Enfin, la nouveauté apportée par cette implémentation, est que ce mécanisme est aussi utilisable dans les pages en XUL !! J'ai porté ma démonstration pour HTML en XUL pour que vous puissiez tester. Cela fait des années que les développeurs XUL attendent ça. En XUL, il existe en effet depuis toujours un mécanisme de drag'n'drop similaire à l'API de HTML5, mais il fallait manipuler des composants XPCOM, chose possible uniquement dans le chrome (dans les extensions, les applications XUL installées en local, mais pas dans les pages XUL distantes). C'est donc une bonne nouvelle :-)

PS: une API de drag and drop similaire mais un peu moins riche existait dans Internet Explorer version 5. Je ne sais pas si elle existe toujours dans les versions 6,7 et 8 de ce navigateur.

Notes

[1] Mise à jour 29/08 : en fait, il faut désactiver la sélection sur l'élément qui sert de point de départ du drag'n'drop, donc dans mon exemple, sur les petites boites à déplacer. Pour Firefox, il faut donc mettre le style -moz-user-select:none;, qui est un style CSS3. Je vais me renseigner si c'est un oubli dans la feuille de style par défaut pour HTML de Firefox ([draggable=true] {-moz-user-select:none;}) ou si c'est volontaire de la part du développeur.

[2] Mise à jour 30/08 : J'ai eu confirmation qu'on ne devrait pas avoir à mettre ce style -moz-user-select et qu'il s'agissait en fait plus d'un bug dans le code du drag'n'drop que d'un oubli dans la feuille de style par defaut de HTML; j'ai donc répertorié ce bug et sa correction est en cours....

[3] dixit la spec mais l'implémentation actuelle dans Firefox ne semble pas permettre ces opérations glisser-déposer entre le navigateur et les autres applications. Est-ce volontaire ? ou pas encore implémenté ? Je n'ai pas eu le temps de chercher à savoir l'origine du problème, peut être est-ce mes tests qui ont été mal écrits