Подтвердить что ты не робот

Что делать, если одновременно срабатывают события "mousemove" и "click"?

Я не знаю, является ли это проблемой только Chrome (не могу проверить сейчас), однако пусть попробуй следующий фрагмент кода, где мы привязываем два события к некоторому элементу:

$("div").on({
    mousemove: function(e) {
        console.log("move");
    },
    click: function(e) {
        console.log("click");
    }
});

Если мы попытаемся щелкнуть элемент, мы обнаружим, что по какой-то причине событие mousemove срабатывает сразу после клика, поэтому в консоли мы имеем:

>> ...
>> click
>> move

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

Обратите внимание, что события mousedown и mouseup работают по тому же сценарию.

Я видел много вопросов о SO по той же проблеме, но ни один (в моем поиске) не дал простой идеи, что делать, чтобы только запустить событие click.

4b9b3361

Ответ 1

Такое поведение является нечетным, и, похоже, оно не происходит повсеместно (это происходит в Chrome/IE для меня, но не для FFX). Я думаю, что ты не получил прямого ответа, потому что на самом деле этого нет.

Возможно, что мышь слегка движется нажатием кнопки, но это, вероятно, не так. Это может быть просто причуда браузера. Это даже не похоже на то же событие, поскольку stopImmediatePropagation в click не останавливает mousemove от стрельбы. Если вы сфокусируете элемент и нажмете кнопку клавиатуры, он фактически вызовет click и только click.

Так как это так странно, кажется, что единственный способ справиться с этим - это времена. Как бы то ни было, я заметил, что click происходит за миллисекунду до mousemove, поэтому вы можете приблизиться, сравнив отметку времени + 2 (или 10):

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

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

Это очень специфично. Вы должны подумать о том, что поведение, которое происходит сразу на mousemove, происходит так часто.

Ответ 2

Mousemove, похоже, привязан к каждому действию мыши в Chrome, поэтому сохраняйте позицию мыши каждый раз, когда мышь "перемещается" и проверяет ее против предыдущей позиции мыши, чтобы подтвердить, что она действительно "перемещена".

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

Демо | Источник

Ответ 3

Это, кажется, ошибка в Chrome, о которой впервые сообщалось в ноябре, и остается открытым.

Chromium Issue 161464

Если вы настроили таргетинг на Chrome, то, возможно, стоит сравнить временные метки событий, чтобы обойти его (используя некоторое минимальное время дельта как предложено @ExplosionPills. Но если вы ищете общее поведение, кажется, что вам лучше рассматривая их как отдельные события, потому что в каждом браузере, но хром (и, возможно, Safari? ошибка помечена как webkit-core), они на самом деле будут отдельными событиями.

Ответ 4

Почему бы просто не проверить, действительно ли мышь двигалась или нет, как показано ниже:

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

(я думаю, что он все равно будет исправлен во всех браузерах)

Ответ 5

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

Ответ 6

Я заметил это поведение, когда мне нужно было различать между mousedown и mouseup, не перетаскивая между ними и mousedown и mouseup с перетаскиванием между ними, решение, которое я использовал, выглядит следующим образом:

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

когда я попробовал это, я заметил, что период простоя простого щелчка делает "isDragging" равным 3, но не очень часто.