Drag and drop HTML5 dans Firefox
Par Laurentj le vendredi, août 29 2008, 00:12 - Technologies Web - Lien permanent
Après les améliorations qui viennent d'être apportées sur le moteur Javascript qui fait repasser Gecko 1.9.1 devant Webkit au niveau des performances de l'execution des scripts JS, voici que Neil Deakin (développeur Mozilla de son état), vient de terminer l'implémentation de l'API drag and drop de HTML5.
On peut donc apporter des fonctions de drag'n'drop dans une page web, tout aussi facilement que ce que l'on peut faire avec des bibliothèques comme jQuery. Sauf qu'il n'y a plus besoin de charger des kilos de scripts JS :-)
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) etdragend
(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) etdragleave
(on sort de l'élément). On reçoit aussi l'évènementdragover
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 dudragover
il a été indiqué que le drop est possible). C'est à ce moment là (ou sur l'évènementdragend
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 ledataTransfer
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 :
- bien sûr, ça sera normalisé, donc on pourra s'attendre à ce que ce soit le même fonctionnement sur les autres navigateurs
- 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)
- 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
Commentaires
Bonne nouvelle pour firefox. Espérons que les autres suivent, c'est une fonctionnalité assez intéressante, surtout son coté inter-applications.
Encore une bonne nouvelle, HTML va apporter plein de bonnes choses, la question c'est quand pourrons nous réellement nous en servir lorsque l'on doit toujours prendre le défunt mais non disparu IE6. C'est promettant pour la suite en tous cas !
C'est dommage qu'on ne pusse pas voir ce qu'on déplace ni que l'on ne puisse pas déplacer les deux boîtes dans une même grande boîte. Limitations de ton script ou de la spéc ?
En passant, lors d'un drag il a mal interprété le mouvement et a chargé la page www.drag.com, je suis au boulot... ;)
Bonjour,
Est-t-il possible d'avoir un lien vers la spécification html5 du drag and drop. En effet je suis aveugle et j'aimerais voir ce qui a été prevu pour l'utilisation du clavier.
La spécification ARIA http://www.w3.org/TR/2008/WD-wai-aria-practices-20080204/#dragdrop propose aussi une gestion du drag and drop mais cela nécessite du java script. Mais par contre sur le papier ca serait tres pratique.
@julien: à la limite, rien n'empêche à une lib comme jquery de faire "comme au bon vieux temps" avec les navigateurs obsolète, et utiliser l'API HTML5 pour les navigateurs modernes ;-)
@thomas : tu es sur quelle plateforme ? windows ? Parce que sous linux, depuis sa version 3, Firefox montre toujours ce que tu déplace. Mais sinon, oui, mon script ne le fait pas, je vais essayer d'ajouter ça : on peut en effet, lors du dragstart, indiquer soit une image, soit un element, dont leur apparence sera utilisée pour "voir" ce qu'on deplace.
Pour l'histoire des deux boites dans une seule, c'est purement un choix de ma part, c'était pour voir comment on pouvait restreindre les drops. Je vais améliorer ça :-)
@Docteur Fas : j'ai donné dans mon billet le lien vers la version du WHATWG, mais je vais le changer pour celui du brouillon "officiel" du w3c. (si il y a des choses qui vous gènent pour lire mon blog, au niveau accessibilité, n'hésitez pas à m'en faire part)
@thomas : j'ai rajouté une boite à déplacer pour s'amuser, et j'ai indiqué ce qu'il fallait utiliser comme image sous le curseur de la souris (en éspérant que ça fonctionne sous windows et mac, en tout cas sous linux c'est impeccable).
Sous Windows impossible de déplacer la troisième boîte (celle avec la bordure) que ce soit avec l'HTML ou le XUL. Et chaque fois que je déplace la 2ème boîte je suis redirigé sur drag2.com :/ J'ai la dernière nightly. Quelqu'un d'autre sous Win pour confirmer ?
@thomas : la troisième boîte, on ne peux plus la déplacer une fois qu'on l'a droppé dans la boite jaune. Est-ce ton cas ?
Et tu n'a pas d'extension installée qui pourrait géner ça ? Tu as bien créer un nouveau profil pour lancer la nightly ?
Je confirme les pépins sous windows avec firefox 3.1a2pre
Redirection vers drag.com et drag2.com
Sinon, ce genre de fonctionnalités, c'est de l'ordre du comportement, ça n'a pas sa place en javascript tout simplement ?
HTML est prévu pour la structure du document et ce genre de mécanisme, je trouve que ça sort de ce cadre perso...
Concernant la visibilité de ce qu'on déplace, je crois que c'est une régréssion. Il y a 3 jours encore je pouvais voir le texte que je déplaçais dans les pages Web.
@olivier confond pas javascript (le langage) et API (les fonctions accessibles via javascript). L'API dont on parle est une extension du DOM HTML, pas de javascript.
Et sinon, que les spécifications de cette API soient incluses dans la spécification HTML ou qu'elles soient dans une spec à part qui serait maintenue par exemple par le groupe de travail webapps du w3c, ça reviendrait au même : on en a besoin.
Pour en revenir aux bugs, possible que ce soit des regressions dans Firefox, je ne sais pas. Peut-être que je ne fais pas tout ce qu'il faut non plus (la spec est un peu dure à comprendre), mais ça marche bien sous linux en tout cas.
cependant c'est vrai que ça pourrait faire parti plutôt de la spec des évènements DOM3
Salut,
concernant ta seconde note de bas de page, je viens de faire des tests sous GNU/Linux dans l'environnement Gnome, avec la démo en XUL: le copier-coller vers d'autres applications fonctionne vers les applis Gnome (un nouveau mail dans Evolution ou Nautilus).
J'ai aperçu dans la spec que dataTransfer pouvait contenir n'importe quel type de données. Tu sais si ça fonctionne ?
glisser-déposer en français ;-)
Pour l'histoire de la redirection vers drag.com et cie, c'est de ma faute : j'ai autorisé la propagation de l'évènement jusqu'au navigateur, et comme c'est une donnée texte que je drag, quand l'interface du navigateur recoit cet évènement, il applique le comportement par défaut.