22

In D3, if you defined a drag function like this:

var drag = d3.behavior.drag()
        .on("drag", function () {alert("drag")})
        .on("dragend", function () {alert("dragEnd")});

You really cannot do the following:

d3.select("#text1")
.on("click", function(d,i) {alert("clicked")})
.call(drag);

Reason is that the click will get fired after that the "dragend" will fire . In my opinion there should be a separate event for clicking because I see a huge difference between dragend and click.

To differentiate between clicking and end of a dragging event in an SVG element, what would be the solution?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
FidEliO
  • 875
  • 3
  • 14
  • 24

2 Answers2

50

The documentation has some explicit examples for this:

When registering your own click listener on draggable elements, you can check whether the click event was suppressed as follows:

selection.on("click", function() {
  if (d3.event.defaultPrevented) return; // click suppressed
  console.log("clicked!");
});

This, along with the stopPropagation() example immediately afterwards, allows you to control which events are fired and handled.

To be clear, differentiating between a drag end and click event is entirely down to you. The easiest way to do this is probably to set a flag when dragging takes place and use that flag to determine whether a dragend or click event should be handled.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • 6
    but this solution doesn't work on Chrome. I mean dragend always fires before click – mhd May 31 '16 at 14:45
1

Since 4.9.0 there is .clickDistance() with which you can control after which distance moved (from where you started dragging) you won't get a click event.

Note that you might get any click event at all if you remove the element from the DOM before release of the button (e.g. by using .raise() in the drag handler).

phk
  • 2,002
  • 1
  • 29
  • 54
  • Does this work in the opposite direction? Where below the click distance, you don't get a drag event? – BallpointBen Jun 16 '20 at 03:26
  • @BallpointBen I guess not but if you have a specific use case then post it as a feature request at https://github.com/d3/d3-drag/issues (best with a demo created using http://blockbuilder.org/ or https://observablehq.com/). – phk Jun 16 '20 at 07:41