在 d3 中拖动后始终抑制单击事件

Posted

技术标签:

【中文标题】在 d3 中拖动后始终抑制单击事件【英文标题】:Always suppress a click event after drag in d3 【发布时间】:2014-05-04 03:45:44 【问题描述】:

点击和拖动事件的解耦在前面的一些问题中讨论过,例如this one

通常,建议在点击处理程序中使用if (d3.event.defaultPrevented === false) ...。但是,如果 mouseup 和 mousedown 不在同一个元素中,这似乎不起作用(至少在某些浏览器中)。 Consider this jsfiddle(代码如下)。这是我想要的行为:单击 SVG 中的任意位置触发单击事件(矩形闪烁),拖动 SVG 中的任意位置拖动矩形。观察到的行为(Chrome 33):如果单击的 mousedown 在矩形内,而 mouseup 在矩形外,则拖动和单击事件都会触发。如果 mousedown 和 mouseup 都在里面或者都在外面,则不会触发 click 事件。

谁能解释一下,如果 mouseup 和 mousedown 不在同一个元素中,为什么会触发 click 事件,以及如何可靠地防止这种情况发生?

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");
    

【问题讨论】:

您的 jsfiddle 完全按照您对我的要求工作(Chrome 32)。 我要求重现的每个人都在使用 Chrome 33;我会尝试挖掘不同版本的 Chrome。 @LeoAlekseyev 你找到解决方法了吗? 【参考方案1】:

将dragBehavior 添加到矩形而不是整个svg 元素。 这是修复http://jsfiddle.net/Mn4Uk/27/的小提琴链接

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

【讨论】:

以上是关于在 d3 中拖动后始终抑制单击事件的主要内容,如果未能解决你的问题,请参考以下文章

D3 js对Android Webview中的拖动事件没有反应

拖动事件后圆圈的Cx没有更新?

d3 js拖动事件侦听器没有收到事件-(d3,反应)

React,如何防止在拖动后执行单击事件?

抑制触发的 Blazor 输入事件

d3拖放鼠标单击事件不会激活