I don't know whether it is only Chrome problem (can't check now), however let's try the following piece of code, where we bind two events to some element:
$("div").on({
mousemove: function(e) {
console.log("move");
},
click: function(e) {
console.log("click");
}
});
If we try to click the element, we'll find that for some reason mousemove
event fires immediately after click, so in console we have:
>> ...
>> click
>> move
DEMO: http://jsfiddle.net/gKqVt/
Note, that mousedown
and mouseup
events work by the same scenario.
I saw many questions on SO about the same problem, but none (in my search) gave the straightforward idea what to do in order to fire the click
event only.
Mousemove appears to be binded to every mouse action there is in Chrome, so store the mouse position every time the mouse "moves" and check it against the previous mouse position to validate that it has indeed "moved"..
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");
}
});
Demo | Source
This appears to be a bug in Chrome that was first reported back in November, and remains open.
Chromium Issue 161464
If you are targeting Chrome specifically then it may be worth comparing the event timestamps to get around it (using some minimum delta time as @ExplosionPills suggested. But if you're looking for general behavior it seems that you're better off treating them as separate events, because in every browser but chrome (and maybe Safari? the bug is labeled as webkit-core) they will in fact be separate events.
This behavior is odd, and it doesn't seem to occur universally (happens in Chrome/IE for me, but not FFX). I think you haven't gotten a straight answer because there isn't one really.
It's possible that the mouse is moved very slightly by the click action, but that's probably not it. Could just be a browser quirk. These don't even seem to be the same event since stopImmediatePropagation
in click
doesn't stop mousemove
from firing. If you focus the element and hit a keyboard button, it will actually trigger click
and only click
.
Since this is so quirky, it seems like the only way to deal with it is times. As much of a kludge as this is, I do notice that click
happens one millisecond before mousemove
, so you could get close by comparing the click timestamp + 2 (or 10):
mousemove: function(e) {
if ($(this).data('lastClick') + 10 < e.timeStamp) {
http://jsfiddle.net/gKqVt/3/
This is very specific, though. You should consider not having behavior that occurs immediately on mousemove since it's so frequent.
Why don't just check that did the mouse really move or not like below:
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
(I think it's will still correct in all browsers)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With