Quantcast
Channel: Murlock » humeur
Viewing all articles
Browse latest Browse all 2

HTML5 – Drag and Drop

$
0
0

Après plusieurs jours de bataille acharnée, je dois m’avouer vaincu, le Drag and Drop de HTML5 a gagné :

  • un comportement différent pour chaque navigateur
  • une norme avec des choix douteux
  • des bugs, pardon, des limitations pour chaque navigateur

Reprenons, tout à ma joie de vouloir ré-implémenter l’un des nombreux modules Vassal (un jeu de carte solo) et continuer ma formation sur HTML5, je me prépare donc mon vi favori (l’unique quoi) et me lance dans la doc.

Firefox / Aurora 16

Avec l’aide de MDN, un prototype fonctionne rapidement mais première (toute petite) désillusion, si l’utilisateur a zoomé sur la page, les coordonnées de setDragImage ne sont pas affectés par le zoom mais heureusement le comportement par défaut montre la carte en transparence, ouf !

pseudo-code:

$('.allow_drag).bind('drag', function( evt ) {
 evt.originalEvent.dataTransfer.setData( "from", "pioche" );
} );
$('.allow_drop').bind('dragover drop', function( evt ) {
 if ( current_target == "defausse" && evt.originalEvent.dataTransfer.getData( "from") == "pioche" )
evt.preventDefault(); // pour dire que j'accepte depuis cette cible sur dragover ou que je traite le drop
} );

Chrome

Je me lance alors sur Chrome, confiant avec mes vrais morceaux d’HTML5 à l’intérieur, que mon code va fonctionner.

Fatalitas ! Rien ne fonctionne, des heures de recherche pour arriver sur la norme officielle : http://developers.whatwg.org/dnd.html :
On ne peut qu’écrire des données dans l’évènement drapstart (le début du drag’n'drop) et lire les données de cet évènement uniquement lors du drop (la fin du truc).
Or il existe juste quelques autres fonctions intermédiaires… comme dragenter, dragleave & dragover qui permette d’indiquer au navigateur que le drop est possible et à l’utilisateur un retour visuel : la norme voudrait que je ne puisse tester si le drop est possible uniquement lors du drop !
Mon sang ne fait qu’un tour : je remplace ma donnée from par un pseudo mime-type : from/pioche.

Autre regret, sur Chrome 21 Linux (du moins sur mes Debian Squeeze ou Wheezy), pas d’image lors du drap’n'drop, seulement une icône générique, là aussi, bug déjà ouvert (référence à retrouver). Pas de souci sur Windows.

nouveau pseudo-code:

$('.allow_drag).bind('drag', function( evt ) {
 evt.originalEvent.dataTransfer.setData( "from/pioche", "pioche" );
} );
$('.allow_drop').bind('dragover drop', function( evt ) {
 if ( current_target == "defausse" && evt.originalEvent.dataTransfer.types[0].split('/')[1] == "pioche" )
   evt.preventDefault(); // pour dire que j'accepte depuis cette cible sur dragover ou que je traite le drop
} );

 

Internet Explorer 9

L’ordinateur de ma femme me faisant de l’oeil, je décide de tester mon code, avec un faible espoir, IE étant le Cthulhu du web c’est bien connu.
Fatalitas… rien, nada, nothing… même pas trace d’un évènement drag
Petite recherche et IE9 ne supporte le drag’n'drop que de la balise img ou d’un lien (avec balise href)… pas de pot, j’utilise un div. I should not pass…

Internet Explorer 10 preview

Ayant installé dans un moment d’égarement une version d’évaluation Windows 8 Entreprise, je lance IE 10.
Tiens, mon drag de div fonctionne, pas mal… mais il y a quand même une exception javascript… lors du drag.
J’inspecte, je m’interroge et je tombe sur setData method. IE ne supporte comme type que ‘Text’ ou ‘URL’. A ce moment là, la coupe est pleine.

Conclusion :

Si je respecte la norme (et IE) :

  • je ne peux que mettre deux informations dans la structure dataTransfer URL & Text, il faudrait peut être que
  • en n’autorisant pas d’autres types que URL & Text, je ne peux pas m’opposer à un drop sur un élèment indésirable. De plus le drop d’une URL lance le chargement de cette URL, ça va être rigolo !
  • je ne peux pas donner d’indication visuelle à l’utilisateur suivant la valeur de ma variable Text car inaccessible dans les évènements dragenter, dragleave ou dragover
  • je ne pourrais pas faire de drag’n'drop entre deux navigation distinctes de mon application
  • et je n’ai pas tester les autres navigateurs comme Safari ou Opera…

Je vais donc me tourner vers une variable globale et m’en tenir à une utilisation légère de la norme HTML5. Dommage, autant les balises video, audio & canvas sont une réussite, autant cette fonctionnalité basique est bancale.



Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images