Reputation: 1849
I've noticed that when I use d3.drag().on('drag',...)
, it fires even when the mouse is not moved. Using the code snippet below (which I pulled from this question), if I simply click and release I still see drag event 1
in the console.
This is an issue because I want to be able to differentiate between a dblclick
and a drag. I've looked at this post and this one, but have been unable to get those solutions to work (it could be because those are old answers and I'm using D3 v4). I did notice that in the fiddle in one of the answers, it's displaying the same issue: both a click event a drag event.
I figured that the drag
event would only be fired if the mouse moved and then I could use it to set a flag that would mark it as dragging, not a doubleclick. However, this doesn't work if drag gets triggered on mouse press.
Very open to suggestions on this one as well as explanations as to why drag
is behaving in this way. I realize this is browser dependent, so I am running Chrome 64.
var count = 0;
d3.select("svg").call(d3.drag().on("start", function() {
console.log("drag started")
}).on("drag", function() {
++count;
console.log("drag event " + count)
}).on("end", function() {
count = 0;
console.log("drag ended")
}))
.as-console-wrapper { max-height: 20% !important;}
svg {
border: 1px solid black;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Upvotes: 2
Views: 1277
Reputation: 687
Sorry this is as an answer, I don't have enough rep to comment yet.
I don't see d3.drag().on('drag',...)
being fired without moving the mouse. I get a start
event on mousedown, and end
event on mouseup and the drag
event fires only when actually dragging. This is the behaviour on all the browsers I have tried so far (Chrome 63, FF 58, IE11). This seems to be inline with the d3.drag API Reference
Upvotes: 0
Reputation: 34489
So d3.drag
has a clickDistance() function that you can call. This allows for a tolerance between a mousedown
and a mouseup
before a drag event is triggered and may well be what you're looking for.
const drag = d3.drag()
.clickDistance(10)
.on("start", () => { console.log("drag started"); })
.on("drag", () => { console.log(`moved by ${d3.event.dx},${d3.event.dy}`); });
Normally this happens because you are actually moving the mouse slightly between a mousedown
and a mouseup
, but only very slightly. I've been looking at similar today, and probably about 25% of the time I move the mouse accidentally (using touch the problem gets worse).
Also to note because you've not really mentioned it but a dblclick
event exists that you can subscribe to. Note that the order of events when using dblclick
looks this (click isn't suppressed):
Upvotes: 1
Reputation: 1849
I did come up with the following work around that solves the issue. Basically just save the mouse position on drag start
and then check to see if the mouse has moved on drag drag
.
While this works, I kind of assumed that drag
would already be doing something like this, or that there would be a cleaner solution out there. Would love to know if someone has something better!
var count = 0;
var dragStartPos = {};
d3.select("svg").call(d3.drag().on("start", function() {
console.log("drag started")
dragStartPos.x = d3.event.x;
dragStartPos.y = d3.event.y;
}).on("drag", function() {
if(d3.event.x != dragStartPos.x ||
d3.event.y != dragStartPos.y) {
++count;
console.log("drag event " + count)
}
}).on("end", function() {
count = 0;
console.log("drag ended")
}))
.as-console-wrapper { max-height: 20% !important;}
svg {
border: 1px solid black;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Upvotes: 0