Decoupling of click and drag events is discussed in some previous questions here, e.g. this one
Typically, it is recommended to use if (d3.event.defaultPrevented === false) {...}
in the click handler. However, this doesn't 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 in SVG triggers click event (rectangle flashes), drag anywhere in SVG drags the rectangle. Observed behavior (Chrome 33): if the mousedown of the click is inside the rectangle and mouseup is outside, both the drag and click events trigger. If both mousedown and mouseup are inside or both are outside, click event is not triggered.
Can someone explain why the click event is triggered if mouseup and mousedown are not in the same element, and how to reliably prevent this from happening?
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");
}
}