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