Что делать, если события "mousemove" и "click" запускаются одновременно?
Я не знаю, является ли это только проблемой Chrome (не могу проверить сейчас), однако давайте попробуем следующий фрагмент кода, где мы привязываем два события к некоторому элементу:
$("div").on({
mousemove: function(e) {
console.log("move");
},
click: function(e) {
console.log("click");
}
});
Если мы попытаемся нажать на элемент, мы найдем это по какой-то причине mousemove
событие срабатывает сразу после нажатия, поэтому в консоли имеем:
>> ...
>> click
>> move
ДЕМО: http://jsfiddle.net/gKqVt/
Обратите внимание, что mousedown
а также mouseup
события работают по тому же сценарию.
Я видел много вопросов на SO об одной и той же проблеме, но ни один (в моем поиске) не дал ясной идеи, что делать, чтобы уволить click
только событие
7 ответов
Это странное поведение, и оно, кажется, не встречается повсеместно (для меня это происходит в Chrome/IE, но не в FFX). Я думаю, что вы не получили прямой ответ, потому что на самом деле его нет.
Вполне возможно, что действие щелчка мышью перемещается очень незначительно, но это, вероятно, не так. Может быть просто причуда браузера. Это даже не кажется тем же событием, так как stopImmediatePropagation
в click
не останавливается mousemove
от стрельбы. Если вы сфокусируете элемент и нажмете кнопку клавиатуры, он фактически сработает click
и только click
,
Поскольку это так странно, кажется, что единственный способ справиться с этим - это времена. Так много, как это, я заметил, что click
происходит за одну миллисекунду до mousemove
, так что вы можете подобраться ближе, сравнив отметку времени клика + 2 (или 10):
mousemove: function(e) {
if ($(this).data('lastClick') + 10 < e.timeStamp) {
Это очень специфично, хотя. Вы должны подумать о том, чтобы не иметь поведения, которое происходит сразу при перемещении мыши, так как это очень часто.
Перемещение мыши, по-видимому, привязано к каждому действию мыши в 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");
}
});
Похоже, что это ошибка в Chrome, о которой впервые было сообщено еще в ноябре, и которая остается открытой.
Если вы ориентируетесь именно на Chrome, то, возможно, стоит сравнить временные метки события, чтобы обойти его (используя некоторое минимальное время дельты, как предложено в @ExplosionPills. Но если вы ищете общее поведение, то, вероятно, лучше рассматривать их как отдельные события, потому что в каждом браузере, кроме chrome (и, возможно, Safari? ошибка отмечена как webkit-core), они фактически будут отдельными событиями.
Почему бы просто не проверить, действительно ли мышь двигалась или нет, как показано ниже:
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");
}
}
(Я думаю, что это все еще будет корректно во всех браузерах)
Я заметил такое поведение, когда мне нужно было различать 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');
}
});
когда я попробовал это, я заметил, что periodacaly простым щелчком делает "isDragging" равным 3, но не очень часто
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');
}
}
});
Попробуй это. Эта работа правильная.
Я добавил следующее в свою функцию mouseMove(event):
function mouseMove(event)
{
if ((event.movementX == 0) && (event.movementY == 0)) return;
Непонятно, почему он срабатывает, когда нет движения, но у меня это сработало. По крайней мере, была проблема в Chrome 102.0.5005.61. Это произошло не несколько лет назад.