Always block click event after dragging in d3

The separation of click and drag events is discussed in some previous questions here, for example. this

It is generally recommended that you use if (d3.event.defaultPrevented === false) {...} in the click handler. However, this does not seem to work (at least in some browsers) if mouseup and mousedown are not in the same element. Consider this jsfiddle (code below). Here is the behavior I want: click anywhere on the SVG trigger of the click event (rectangular flashes), drag anywhere on the SVG by dragging the rectangle. Observed behavior (Chrome 33): if the mouse in the click is inside the rectangle and the mouse is outside, three drag-and-drop events are triggered. If both mice and the mouse are inside or both are outside, the click event does not fire.

Can someone explain why the click event is fired if mouseup and mousedown are not in the same element and how to reliably prevent this?

 var container, rect, dragBehavior; svg = d3.select('svg').attr("width", 500).attr("height", 300); container = svg.append('g'); rect = container.append('rect').attr('width', 100).attr('height', 100); dragBehavior = d3.behavior.drag() .on('dragend', onDragStart) .on('drag', onDrag) .on('dragend', onDragEnd); svg.call(dragBehavior).on('click', onClick); function flashRect() { rect.attr('fill', 'red').transition().attr('fill', 'black'); } function onDragStart() { console.log('onDragStart'); } function onDrag() { console.log('onDrag'); var x = (d3.event.sourceEvent.pageX - 50); container.attr('transform', 'translate(' + x + ')'); } function onDragEnd() { console.log('onDragEnd'); } function onClick(d) { if (d3.event.defaultPrevented === false) { console.log('onClick'); flashRect(); } else { console.log("default prevented"); } } 
+7
javascript
source share
1 answer

Add dragBehavior to the rectangle instead of the entire svg element. Here is a link to the script with the fix http://jsfiddle.net/Mn4Uk/27/

 rect .call(dragBehavior) .on('click', onClick); 
0
source share

All Articles