Javascript D3对于具有拖动行为的图元,区分单击和拖动

Javascript D3对于具有拖动行为的图元,区分单击和拖动,javascript,drag-and-drop,d3.js,Javascript,Drag And Drop,D3.js,在使用D3.js v3绑定到这两个元素的元素上,我无法成功区分单击事件和拖动事件。下面代码中的圆圈指定了拖动行为和单击侦听器。 每当我单击示例中的圆圈时,控制台就会记录拖动事件以及单击事件。我在拖动时也会得到相同的行为,首先记录拖动事件,然后在鼠标上记录单击事件 单独处理这些事件的正确方法是什么? 用例是尝试在树布局中处理节点单击和节点拖放。您可以区分单击和拖动启动,但很难区分鼠标下移和拖动启动 dragstart将在您开始拖动操作时触发,这意味着当您执行mousedown时。这就是为什么。每

在使用D3.js v3绑定到这两个元素的元素上,我无法成功区分
单击
事件和
拖动
事件。下面代码中的圆圈指定了拖动行为和
单击
侦听器。

每当我单击示例中的圆圈时,控制台就会记录
拖动事件以及
单击事件。我在拖动时也会得到相同的行为,首先记录
拖动
事件,然后在
鼠标上记录
单击
事件

单独处理这些事件的正确方法是什么?

用例是尝试在树布局中处理节点单击和节点拖放。

您可以区分
单击
拖动启动
,但很难区分
鼠标下移
拖动启动

dragstart
将在您开始拖动操作时触发,这意味着当您执行
mousedown
时。这就是为什么。每当您
单击
,就会触发
拖动启动
。(一个
点击
是一个
鼠标向下
+
鼠标按下

因此,防止被触发的点击应该起作用。在代码中,应该添加默认值,正如Lars Kotthoff所暗示的那样。但不要将其放在dragstart函数中:

var dragCircle = d3.behavior.drag()
    .on('dragstart', function () {
    d3.event.sourceEvent.stopPropagation();
    d3.event.sourceEvent.preventDefault(); <-- Remove This
    console.log('Start Dragging Circle');
})
var dragCircle=d3.behavior.drag()
.on('dragstart',函数(){
d3.event.sourceEvent.stopPropagation();

d3.event.sourceEvent.preventDefault();缺少的关键位是检查事件的默认行为是否已被阻止。也就是说,d3.event.preventDefault()有一个匹配的同级
--
d3.event.defaultPrevented
。您需要在
单击
处理程序中检查此项,以查看是否正在进行任何拖动操作


另请参见对.d3.event.sourceEvent.preventDefault()的回答。

d3.event.sourceEvent.preventDefault()不能按预期工作,或者与其说是不一致

我遇到了这个问题,为了区分这两个事件,我在
onDrag
事件中使用了一个布尔值
isDragged
。因此,如果设置了该值,则在对象上执行
拖动
事件,如果未设置,则执行
单击
事件。
另外,正常单击对象会触发其
dragstart
dragend
事件,但不会触发
onDrag
事件。

您是否也尝试过在
dragend
上执行
preventDefault()
等操作?@larskothoff是的,也没有用:(你看到了吗?嗨,拉尔斯,非常感谢你指出了正确的方向。这是一个解决方案,如果你愿意的话,也许可以用类似于@leMoisela的答案来回答,这样我就可以相信你了?谢谢你的帮助和关注。@Larskothoff,谢谢你让我找到了正确的方向!我在努力寻找如何捕捉一个拖动事件不幸的是,d3.event.defaultPrevented在d3.event.defaultPrevented中的工作并不一致。至少在Chrome中,我观察到,尽管进行了此检查,单击处理程序有时仍会被拖动执行。@BruceHill可能值得发布一个单独的问题,其中包含您给出的特定问题,即该问题非常古老。@BruceHill我注意到在Windows上的Chrome中也存在同样的问题,它不能始终阻止默认设置。我也有这个问题,在Chrome中也观察到了。我相信这与我们的可拖动节点有关,这些节点很复杂,包含多个路径和文本元素。我已经通过更改d3:my dragRestore调用“修复”了这个问题(从v3.5.8开始,第1235行)读取dragRestore(拖动);而不是dragRestore(拖动&&d3.event.target===target);我对此发表了评论,维护人员正在通过
var dragCircle = d3.behavior.drag()
    .on('dragstart', function () {
    d3.event.sourceEvent.stopPropagation();
    d3.event.sourceEvent.preventDefault(); <-- Remove This
    console.log('Start Dragging Circle');
})
g.selectAll('circle').data([{
    cx: 90,
    cy: 80
}]).enter()
    .append('circle')
    .attr('cx', function (d) {
    return d.cx
})
    .attr('cy', function (d) {
    return d.cy
})
    .attr('r', 30)
    .call(dragCircle)
    .on('click', click);

function click(d) {
  if (d3.event.defaultPrevented) return; <-- Add d3.event.defaultPrevented
  console.log('clicked');
}