D3 区分具有拖动行为的元素的单击和拖动
D3 Differentiate between click and drag for an element which has a drag behavior
我无法使用 D3 v3 成功区分绑定到两者的元素上的click
事件和drag
事件.js v3。 下面代码中的圆圈被分配了一个拖动行为和一个click
侦听器。在这里演示
var dragGroup = d3.behavior.drag()
.on('dragstart', function () {
console.log('Start Dragging Group');
})
.on('drag', function (d, i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this).attr("transform", "translate(" + d.x + "," + d.y + ")");
});
var dragCircle = d3.behavior.drag()
.on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
d3.event.sourceEvent.preventDefault();
console.log('Start Dragging Circle');
})
.on('drag', function (d, i) {
d.cx += d3.event.dx;
d.cy += d3.event.dy;
d3.select(this).attr('cx', d.cx).attr('cy', d.cy);
});
var svg = d3.select('body').append('svg').attr('viewBox', '-50 -50 300 300');
var g = svg.selectAll('g').data([{
x: 10,
y: 10
}])
.enter().append('g').call(dragGroup);
g.append('rect').attr('width', 100).attr('height', 100);
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', function () {
console.log('clicked circle');
});
每当我单击示例中的圆圈时,我都会得到控制台记录drag
事件以及click
事件。 我在拖动时也会得到相同的行为,首先记录drag
事件,mouseup
记录click
事件。
分别处理这些事件的正确方法是什么?
用例是尝试在树布局中处理节点单击和节点拖放。
缺少的关键位是检查事件的默认行为是否已被阻止。也就是说,d3.event.preventDefault()
有一个匹配的兄弟姐妹 - d3.event.defaultPrevented
。您需要在click
处理程序中检查这一点,以查看是否正在进行任何拖动操作。
另请参阅此问题的答案。
你可以区分click
和dragstart
,但很难区分mousdown
和dragstart
。
dragstart
将在您开始拖动操作时触发,这意味着当您执行mousedown
时。这就是原因。每当你click
,dragstart
都会triggered
。(click
是mousedown
+ mouseup
)。
因此,防止触发点击应该有效。在你的代码中,你应该添加 preventDefault,正如 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');
})
并将其添加到正确的位置(在单击函数中),并使用d3(d3.event)正确编写。默认已阻止)
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');
}
请参阅更新版本。现在,拖动时,不再触发click
。
请记住,单击时,仍会触发dragstart
。(但不是drag
)
d3.event.sourceEvent.preventDefault()
无法按预期工作,或者说不一致。
我遇到了这个问题,为了区分这两个事件,我在onDrag
事件中使用了布尔值isDragged
。因此,如果设置了此值,则对对象执行drag
事件,如果未执行click
则执行该事件。此外,对对象的正常单击会触发其dragstart
和dragend
事件,但不会触发onDrag
事件。
- 如何使元素在可拖动元素内可单击
- 拖动开始时更改可拖动元素的大小
- 无法为HTML5中具有画布和图像的可拖动元素设置“拖动图像”
- 具有可拖动元素的HTML到PDF
- 可缩放容器鼠标上的可拖动元素在创建时从辅助对象上浮动
- 删除所有可拖动元素后如何显示消息
- 将可拖动元素与从父项位置开始的网格对齐
- 拖动元素时,如何获取要替换的元素的位置
- 将id为X的可拖动元素拖放到id为Y的容器
- 在没有jQuery的情况下拖动元素
- 可拖动元素在悬停在另一个'It’s draggable
- 拖动时更改HTML5可拖动元素的“克隆”文本
- Javascript:当元素中有<选择>时,可拖动元素搞砸了
- 是否有可能知道 jquery 可拖动元素将恢复到哪里
- 如何将键控事件与 JQuery-ui 可拖动元素一起使用
- jQuery UI 可拖动元素位于其他可拖动元素下
- 从拖动元素中获取 HTML5 自定义数据属性
- 使用 D3.js 拖动元素时滚动
- 同步两个可拖动元素的位置
- 如何从可拖动元素中删除项目符号