web-dev-qa-db-fra.com

Que faire si les événements "mousemove" et "click" se déclenchent simultanément?

Je ne sais pas s'il s'agit seulement d'un problème Chrome (ne peut pas vérifier maintenant), mais essayons le code suivant, dans lequel 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 constaterons que, pour une raison quelconque, l'événement mousemove se déclenche immédiatement après le clic. Par conséquent, dans la console, nous avons:

>> ...
>> click
>> move

DEMO: http://jsfiddle.net/gKqVt/

Notez que les événements mousedown et mouseup fonctionnent selon le même scénario.

J'ai vu beaucoup de questions sur SO à propos du même problème, mais aucune (dans ma recherche) ne donnait la simple idée de ce qu'il fallait faire pour déclencher l'événement clickuniquement.

23
VisioN

Ce comportement est étrange et ne semble pas se produire de manière universelle (cela se produit dans Chrome/IE pour moi, mais pas dans FFX). Je pense que vous n’avez pas obtenu de réponse claire, car il n’en existe pas vraiment.

Il est possible que la souris soit déplacée très légèrement par l'action du clic, mais ce n'est probablement pas ça. Pourrait juste être une bizarrerie de navigateur. Cela ne semble même pas être le même événement puisque stopImmediatePropagation dans click n'arrête pas mousemove de tirer. Si vous focalisez l'élément et appuyez sur un bouton du clavier, cela déclenchera click et only click.

Comme c'est tellement bizarre, il semble que la seule façon de régler le problème est de prendre son temps. Malgré tout ce que cela a à dire, je remarque que click se produit une milliseconde avant mousemove, vous pouvez donc vous en approcher en comparant l'horodatage du clic + 2 (ou 10):

mousemove: function(e) {
    if ($(this).data('lastClick') + 10 < e.timeStamp) {

http://jsfiddle.net/gKqVt/3/

Ceci est très spécifique, cependant. Vous devriez envisager de ne pas avoir de comportement qui se produit immédiatement lors du déplacement de la souris, car il est si fréquent.

3
Explosion Pills

Il semble que Mousemove soit lié à chaque action de la souris dans Chrome. Conservez la position de la souris chaque fois que celle-ci se "déplace" et comparez-la à la position précédente de la souris pour valider qu'elle a bien été "déplacée" ..

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");
    }
});

Démo | La source

8
extramaster

Cela semble être un bogue dans Chrome qui a été signalé pour la première fois en novembre et qui reste ouvert.

Chrome Numéro 161464

Si vous ciblez spécifiquement Chrome, il peut être utile de comparer les horodatages des événements (en utilisant un temps delta minimal suggéré par @ExplosionPills. Toutefois, si vous recherchez un comportement général, il semble préférable de les traiter comme événements distincts, car dans tous les navigateurs sauf le chrome (et peut-être Safari? le bogue est étiqueté en tant que webkit-core), il s'agira en fait d'événements distincts.

7
Ben McCormick

Pourquoi ne pas 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");
    }
}

FIDDLE DEMO

(Je pense que cela sera toujours correct dans tous les navigateurs)

1
Ben Mack

J'ai remarqué ce comportement lorsque je devais faire la différence 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 périodiquement, un simple clic rend "isDragging" égal à 3 mais pas très souvent

0
AZNI HAMZA
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');
          }
        }
  });

Essaye ça. Celui-ci fonctionne correctement.

0
Hanul Choi