Que faire si les événements" mousemove "et" click " se déclenchent simultanément?
Je ne sais pas si c'est seulementChrome problème (ne peut pas vérifier maintenant), cependant essayons le morceau de code suivant, où nous lions deux événements à un élément:
$("div").on({
mousemove: function(e) {
console.log("move");
},
click: function(e) {
console.log("click");
}
});
Si nous essayons de cliquer sur l'élément, nous trouverons que pour une raison quelconque mousemove
l'événement se déclenche immédiatement après le clic, donc dans la console nous avons:
>> ...
>> click
>> move
DÉMO: http://jsfiddle.net/gKqVt/
Notez que les événements mousedown
et mouseup
fonctionnent selon le même scénario.
J'en ai vu beaucoup questions sur SO sur le même problème, mais aucun (dans ma recherche) n'a donné l'idée simple de ce qu'il faut faire pour déclencher l'événement click
seulement.
6 réponses
Ce comportement est étrange, et il ne semble pas se produire universellement (arrive dans Chrome / IE pour moi, mais pas FFX). Je pense que vous n'avez pas eu une réponse directe parce qu'il n'y en a pas vraiment.
Il est possible que la souris soit très légèrement déplacée par l'action de clic, mais ce n'est probablement pas le cas. Pourrait juste être une bizarrerie de navigateur. Ceux-ci ne semblent même pas être le même événement puisque stopImmediatePropagation
dans click
n'empêche pas mousemove
de tirer. Si vous concentrez l'élément et appuyez sur un bouton du clavier, il sera en fait déclencheur click
et seulement click
.
Comme c'est tellement bizarre, il semble que la seule façon de le faire est le temps. Même si c'est un kludge, je remarque que click
arrive une milliseconde avant mousemove
, ainsi, vous pouvez vous rapprocher en comparant l'horodatage de clic + 2 ( ou 10):
mousemove: function(e) {
if ($(this).data('lastClick') + 10 < e.timeStamp) {
C'est très spécifique, cependant. Vous devriez envisager de ne pas avoir de comportement qui se produit immédiatement sur mousemove comme il est si fréquent.
Mousemove semble être lié à chaque action de la souris dans Chrome, alors stockez la position de la souris chaque fois que la souris "se déplace "et vérifiez-la par rapport à la position précédente de la souris pour valider qu'elle a effectivement"bougé"..
var currentPos=[];
$("div").on({
mousemove: function(e) {
if (e.pageX!==currentPos[0] && e.pageY !==currentPos[1]){
currentPos=[e.pageX,e.pageY];
this.innerHTML = "Event: " + e.type;
console.log("move");
}
},
click: function(e) {
this.innerHTML = "Event: " + e.type;
console.log("click");
}
});
Cela semble être un bug dans Chrome qui a été signalé pour la première fois en novembre, et reste ouvert.
Si vous ciblez Chrome spécifiquement, il peut être utile de comparer les horodatages d'événements pour le contourner (en utilisant un temps delta minimum comme suggéré par @ExplosionPills. Mais si vous cherchez un comportement général, il semble que vous feriez mieux de les traiter comme des événements séparés, car dans tous les navigateurs sauf chrome (et peut-être Safari? le bug est étiqueté comme webkit-core), ils seront en fait des événements distincts.
Pourquoi ne pas simplement vérifier que la souris a vraiment bougé ou pas comme ci-dessous:
function onMouseDown (e) {
mouseDown = { x: e.clientX, y: e.clientY };
console.log("click");
}
function onMouseMove (e) {
//To check that did mouse really move or not
if ( e.clientX !== mouseDown.x || e.clientY !== mouseDown.y) {
console.log("move");
}
}
(je pense que c'est toujours correct dans tous les navigateurs)
var a,b,c,d;
$(".prd img").on({
mousedown: function(e){
a= e.clientX, b= e.clientY;
},
mouseup: function(e){
c= e.clientX, d= e.clientY;
if(a==c&&b==d){
console.log('clicked');
}
}
});
Essayez ceci. Ce un travail correct.
J'ai remarqué ce comportement quand j'avais besoin de différencier entre mousedown et mouseup sans glisser entre les deux et mousedown et mouseup avec glisser entre eux, la solution que j'ai utilisée est la suivante:
var div = $('#clickablediv');
var mouseDown = false;
var isDragging = 0;
div.mousedown(function () {
isDragging = false;
mouseDown = true;
}).mousemove(function () {
if (mouseDown) isDragging++;
}).mouseup(function () {
mouseDown = false;
var wasDragging = isDragging;
isDragging = 0;
if (!wasDragging || wasDragging<=1) {
console.log('there was no dragging');
}
});
Quand je l'ai essayé, j'ai remarqué que periodacaly un simple clic rend "isDragging" égal à 3 mais pas très fréquemment