Jump to content

Concurrence Drag & Drop Javascript / Navigateur


Recommended Posts

Bonjour à tous,

Voila j'ai ecrit une petite classe en javascript qui permet de faire du drag & drop sur des images d'une page HTML. Ca marche à peu près, excepté que l'effet est en concurrence avec le drag & drop proposé par les navigateurs sur les images.

Les navigateurs (en tout cas Firefox et IE7) permettent de capturer les images lorsqu'on maintient le clic gauche enfoncé. Le curseur se change alors en un rond barré sur le reste de la page, la où on ne peut déposer l'image. Le problème est que lorsque j'essaie de faire du drag & drop sur une image avec mon script activé, ce comportement des navigateurs perturbe mon script.

Quelqu'un aurait-il une idée pour bloquer le drag & drop du navigateur ?

J'ai envisagé de mettre un autre calque au dessus des images pour éviter que les navigateurs les considèrent comme telles, mais je ne suis pas sûr du résultat.

Merci d'avance pour vos réponses.

Bonne soirée.

Link to comment
Share on other sites

Salut,

J'avais essayé de faire la même chose que toi, et il me semble que j'utilisais à chaque fois un div, et l'image se trouvait en background. Donc tu déplace le div et lorsque tu met ta souris dessus le navigateur te fait pas chier parce que c'est une image.

Link to comment
Share on other sites

Tout d'abord, merci pour vos réponses,

LukeSkyPator, c'est un simple site xHTML + js, pas de XUL. Les images proviennent du serveur.

ZyriK, pour ta solution qui consiste à mettre l'image en background, j'y avais déjà pensé, mais j'aimerai pouvoir garder des balises images, comme c'est fait sur ce site : https://www.panic.com/. Leur script est ici, et je ne vois pas du tout ce qu'ils ont fait pour ne pas avoir le drag & drop du navigateur.

Si quelqu'un à une idée, je suis preneur, sinon, je me contenterai de mettre les images en background.

Bonne journée.

Link to comment
Share on other sites

Non ca n'as aucun rapport ^^

La seule difference entre la balise img se fermant par "/>" et celle se fermant par ">" c'est que l'une est en XHTML et que l'autre en HTML.

Globalement le XHTML est légèrement plus strict au niveau du code que le HTML qui autorise encore les "<br>", les "<center>" ... est plus tolérant.

Link to comment
Share on other sites

Leur code n'est pas vraiment caca, c'est juste que c'est du vieux HTML4 (transitional). Ils signalent d'ailleurs en haut de leur page qu'ils vont bientôt la refaire.

Par contre, l'idée est bonne, parce qu'il n'ont pas mis de DTD sur le document, ce qui signifie (si je me trompe pas) que la navigateur interprète la page en "quirks mode". Je me suis dit que peut être, dans ce mode, le navigateur ne mettait pas en place la possibilité de faire du drag & drop sur les images. Malheureusement (ou pas, car ce ne serait pas très rigoureux), j'ai essayé, et ca ne marche pas.

Au final, on retombe sur ce qu'a dit Zyrik : aucun rapport.

Pour l'instant, j'ai mis mes images en background d'un conteneur, et comme l'avait dit Zyrik, j'ai plus le problème. Mais je suis quand même curieux de savoir comment ils ont fait sur le site en lien dans mon post précédent.

Link to comment
Share on other sites

C'est vrai que je ne sais pas non plus comment qu'ils ont fait sur leur site ... Je suis pas très bon en javascript donc je peux pas trop d'aider d'avantage, et j'ai pas eu le courage de décortiquer leur code ;)

Et en effet c'est pas très rigoureux de ne pas mettre de DTD sur la page, de nombreuses incompatibilités apparaissent entre les différents navigateurs qui n'interprètent pas la page de la même manière.

Link to comment
Share on other sites

C'est simple, tout le secret ce cache ici :

if (isNav4) {
 document.captureEvents(Event.MOUSEUP|Event.MOUSEDOWN);
}

document.onmousedown=doDown;
document.onmouseup=doUp;

Dans l'ordre d'execution des événements. Pour plus d'infos sur le sujet, un lien très instructif vers un article de Peter Paul Koch sur les phases de "Bubbling" et "Catching" en javascript :

http://www.quirksmode.org/js/events_order.html

Bonne chance Jim :D

Link to comment
Share on other sites

Salut, je viens de lire ton message, je n'ai pas encore pu tester, mais je ne doute pas que ça fonctionne.

Je connaissais le principe d'ordonnancement des événements, mais je pensais que le navigateur faisait une distinction entre les événements de la page qu'il est en train d'afficher et ses événements internes. C'est vraiment intéressant de pouvoir interagir sur le comportement du navigateur de cette façon.

Je m'attendais plutôt à un bidouillage qui empêcherait le navigateur de déclencher cet événement, comme le fait l'attribut autocomplete="off" (non officiel) sur les balises input pour supprimer l'apparition du champ d'auto complétion.

En tout cas merci à toi de nous avoir apporté la solution.

Link to comment
Share on other sites

Bonsoir à tous,

Me voila de retour après avoir effectué quelques tests. J'ai essayé de creuser un peu autour de cette gestion d'événements. La méthode « captureEvents » de l'objet « window » ou « document » permet effectivement de capturer les événements (logique, vous me direz :eeek2: ) directement au niveau du document ou de la fenêtre. Les événements sont bien « capturés » et donc interrompus. C'est expliqué sur cette page du MDC (voir la partie « Notes » ) : http://developer.mozilla.org/en/docs/DOM:w...w.captureEvents.

J'ai donc ajouté ces quelques lignes qui permettent d'intercepter l'enfoncement du bouton gauche de la souris :

	
<script type="text/javascript">
document.captureEvents(Event.MOUSEDOWN);
document.onmousedown = test;
function test(evenement) {
		   return false;
}
</script>

Et ça fonctionne. Ca prouve que le navigateur ajoute sa propre couche de gestion d'événement au même niveau que ceux de la page. Par contre, pour ne pas bloquer l'événement « onmousedown » sur toute la page, il est nécessaire de vérifier que le n½ud à l'origine du clic est bien un n½ud sur lequel on veut bloquer l'événement, et j'ai peur que ca ralentisse un peu le navigateur. De plus, je ne suis pas sur que ca fonctionne puisque captureEvents semble casser la chaine de l'événement.

Par ailleurs, cette méthode est obsolète (supprimée dans firefox 3). Il faut désormais utiliser addEventListener.

La suite, donc, au prochain post, avec une solution valide W3C.

Link to comment
Share on other sites

Par contre, pour ne pas bloquer l'événement « onmousedown » sur toute la page, il est nécessaire de vérifier que le n½ud à l'origine du clic est bien un n½ud sur lequel on veut bloquer l'événement, et j'ai peur que ca ralentisse un peu le navigateur.

Pour cela les propriétés de l'objet d'activation sont tes amies !

function maFonction(e){ //ou "e" est l'objet d'activation, pas un paramètre transmis via l'appel
  var evt = e || window.event;
  var evtTarget = evt.target || evt.srcElement;
  // if(evtTarget == ceQueJeVeux) courirToutNuDansLaNeige();
}

PS : par contre je ne sais pas si ça fonctionne avec "captureEvent" je ne me sers que des écouteurs...

Link to comment
Share on other sites

Oui bien sûr, mais le problème est bien de savoir si cela fonctionne aussi avec captureEvents, puisque, si j'ai bien compris, cette méthode stoppe la chaine de propagation (le capturing) de l'événement au niveau de "document" ou "window".

De toute manière, je préfère utiliser des écouteurs valides W3C.

Link to comment
Share on other sites

  • 2 weeks later...

Je reviens à la charge avec un peu (beaucoup) de retard.

Pour conclure le topic, j'ai donc essayé de résoudre mon problème avec du code valide W3C. Cela donne les lignes suivantes :

		<script type="text/javascript">
		document.addEventListener("mousedown",test,false);
		function test() {
			//document.body.style.backgroundColor = "black";
			return false;
		}
	</script>

Avec ceci, l'événement est bien capturé (le body devient noir si on décommente la ligne concernée) mais le drag & drop du navigateur reste... Et en mettant le troisième argument de "addEventListener" à "true", ça ne change rien.

Link to comment
Share on other sites

J'ai à nouveau fait quelques tests en utilisant la méthode "stopPropagation" de l'objet "event" pour tenter de stopper la propagation de l'événement. Encore une fois, ça ne marche pas sous Firefox. Par contre, j'ai eu la bonne surprise de constater que les deux solutions (celle non valide et celle valide) fonctionnent toutes les deux sous Opera. Je n’ai plus d'autre idées pour faire avancer le problème :reflechis:

A part ca, j'ai une question subsidiaire, toujours concernant le drag & drop. Comment faire pour détecter la position d'un click sur un élément qui est recouvert par un autre ?

Je m'explique : j'ai fait un drag & drop ou l'on doit cliquer pour prendre un objet et cliquer à nouveau pour le déposer. Lorsque l'on clique pour poser l'objet, je voudrais pouvoir détecter le noeud sur lequel on se situe, sachant que sous la souris, on a à ce moment l'objet en cours de drag & drop. Pour l'instant, je compare la position de l'objet en cours de déplacement (autrement dit la position de la souris) et toutes les positions des noeuds en dessous. Je trouve cette technique très lourde.

J’ai ensuite pensé que le bubbling de l'événement me permettrait de résoudre le problème, mais ce n'est pas le cas. En effet le bubling remonte de parents en parents dans le document xHTML, mais pas géographiquement sur la page. Or l'imbrication des éléments dans le code ne correspond plus du tout à leur placement sur la page à partir du moment ou l'on a des noeuds fixés en « position : absolute » dans le CSS.

J'espère que je suis parvenu à me faire comprendre clairement :mdr: .

Merci d'avance pour vos réponses.

Link to comment
Share on other sites

  • 2 weeks later...

Salut Ultimate,

j'ai cherché également une solution à ce problème, et j'ai trouvé une solution à partir de leur script : il faut intercepter l'evenement mousemove dans la fonction de gestion de l'evenement mousedown, car c'est sur mousemove après un mousedown que le browser intitie ce comportement gênant.

Je peux t'envoyer un exemple qui marche si tu veux.

++

Link to comment
Share on other sites

Salut et merci pour ta contribution,

J'ai essayé de capturer l'événement "onmousemove" après un "onmoudown" comme tu me l'as décrit :

		
	   <script type="text/javascript">
		document.addEventListener("mousedown",test,false);
		function test(evenement) {
			document.addEventListener("mousemove",bloque,false);
			return false;
		}
			function bloque(evenement) {
			//document.body.style.backgroundColor = 'black';
			return false;
		}
	</script>

Avec ce code, je n'ai aucun résultat. L'événement "onmousemove" est bien détecté (le body devient bien noir en décommentant la ligne), mais le comportement du navigateur ne change pas.

Toutefois, j'ai poursuivi mes recherches, et je suis tombé sur la méthode "preventDefault" de l'objet event :

		<script type="text/javascript">
		document.addEventListener("mousedown",test,false);
		function test(evenement) {
			evenement.preventDefault();
		}
	</script>

Et la miracle, ça marche !

Je suis curieux de savoir comment mettre en oeuvre ta méthode. J'aimerai aussi comprendre comment les navigateurs gèrent leurs événements internes et pourquoi un simple "stopPropagation" ne fonctionne pas. Si quelqu'un peut m'éclairer (ainsi que sur ma deuxième question dans mon post précédent).

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...