d3js阻止点击拖动事件
d3js preventing drag on click event
我正在尝试在d3js中绘制一个UI,其中我有一个顶部面板,我应该能够将drag
和drop
元素复制到一个组中并将它们复制。我已经实现了这个目标,但我的代码中有一个错误。我实际想做的是拖动circle
并复制它。但当我单击顶部面板中的circle
时,它会自动触发拖动事件并自行复制。我该如何制止这种行为?
<svg height="600" width="600" style="background: black">
<g>
<rect x="0" y="0" , width="600" height="40" style="fill:gold;"></rect>
<circle id='drag' cx="15" cy="20" init-cx="15" init-cy="20" r="10"
style="stroke: white; stroke-width: 2px; fill:blue"/>
</g>
<g id="playground">
<g>
<circle id='top' cx="180" cy="120" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
<g>
<circle id='top' cx="200" cy="220" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
<g>
<circle id='top' cx="320" cy="150" r="50" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
</g>
</svg>
<script>
$(document).ready(function () {
var move = d3.behavior.drag()
.on('drag', function () {
console.log('dragging');
var curr = d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
})
.on('dragend', function () {
var curr = d3.select(this);
d3.select('#playground')
.append('circle')
.attr({
cx : curr.attr('cx'),
cy : curr.attr('cy'),
r : curr.attr('r')
})
.style({
fill : 'white',
stroke : 'red',
'stroke-width' : '2px'
})
;
curr.attr({
cx : curr.attr('init-cx'),
cy : curr.attr('init-cx')
});
})
;
d3.select('#drag').call(move);
});
</script>
这是我工作的小提琴。https://jsfiddle.net/fawzan/my2g724L/
希望这对您有用,看一看我在"dragend"中添加了一些代码,也就是说,在这里,我通过使用circle的属性(如init-cx和init-cy)来决定是否在操场上创建/附加一个圆圈。我添加的代码是
var initX = (curr.attr('init-cx')*1);
var currX = (curr.attr('cx')*1);
var initY = (curr.attr('init-cy')*1);
var currY = (curr.attr('cy')*1);
if(((currX) > (initX+20)) || ((currY) > (initY+20))){
//Here code to append a circle to playground
}
Fiddle
:D
您只需要检查拖动结束事件的目标是同一个圆,并且只有在它们不匹配的情况下才复制该圆。
.on('dragend', function() {
if (d3.event.sourceEvent.target != this) {
var curr = d3.select(this);
d3.select('#playground')
.append('circle')
.attr({
cx: curr.attr('cx'),
cy: curr.attr('cy'),
r: curr.attr('r')
})
.style({
fill: 'white',
stroke: 'red',
'stroke-width': '2px'
});
curr.attr({
cx: curr.attr('init-cx'),
cy: curr.attr('init-cx')
});
}
});
var move = d3.behavior.drag()
.on('drag', function() {
console.log('dragging');
console.log(this)
console.log(this)
var curr = d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
})
.on('dragend', function() {
if (d3.event.sourceEvent.target != this) {
var curr = d3.select(this);
d3.select('#playground')
.append('circle')
.attr({
cx: curr.attr('cx'),
cy: curr.attr('cy'),
r: curr.attr('r')
})
.style({
fill: 'white',
stroke: 'red',
'stroke-width': '2px'
});
curr.attr({
cx: curr.attr('init-cx'),
cy: curr.attr('init-cx')
});
}
});
d3.select('#drag').call(move);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg height="600" width="600" style="background: black">
<g>
<rect x="0" y="0" , width="600" height="40" style="fill:gold;"></rect>
<circle id='drag' cx="15" cy="20" init-cx="15" init-cy="20" r="10" style="stroke: white; stroke-width: 2px; fill:blue" />
</g>
<g id="playground">
<g>
<circle id='top' cx="180" cy="120" r="30" style="stroke: white; stroke-width: 2px; fill:white" />
</g>
<g>
<circle id='top' cx="200" cy="220" r="30" style="stroke: white; stroke-width: 2px; fill:white" />
</g>
<g>
<circle id='top' cx="320" cy="150" r="50" style="stroke: white; stroke-width: 2px; fill:white" />
</g>
</g>
</svg>
单击时,您的curr.attr('cx')
偏移量返回15。因此,您可以通过在dragend方法上添加条件来阻止默认操作:
if(curr.attr('cx')==15){
return false;
}
更通用:
var isClicked = false;
var move = d3.behavior.drag()
.on('dragstart', function() {
isClicked = true;
})
.on('drag', function() {
isClicked = false;
var curr = d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
})
.on('dragend', function() {
var curr = d3.select(this);
if (!isClicked) {
d3.select('#playground')
.append('circle')
.attr({
cx: curr.attr('cx'),
cy: curr.attr('cy'),
r: curr.attr('r')
})
.style({
fill: 'white',
stroke: 'red',
'stroke-width': '2px'
});
}
curr.attr({
cx: curr.attr('init-cx'),
cy: curr.attr('init-cx')
});
});
d3.select('#drag').call(move);
d3.select('#drag').on('click', click);
function click(d) {
isClicked = true;
}
结账Fiddle:
更多信息
使用布尔值监视是否启动拖动。通过这种方式,您可以停止拖动功能。
$(document).ready(function () {
var isDragged = false;
var move = d3.behavior.drag()
.on('drag', function () {
console.log('dragging');
isDragged = true;
var curr = d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
})
.on('dragend', function () {
if (!isDragged) return;
isDragged = false;
var curr = d3.select(this);
d3.select('#playground')
.append('circle')
.attr({
cx : curr.attr('cx'),
cy : curr.attr('cy'),
r : curr.attr('r')
})
.style({
fill : 'white',
stroke : 'red',
'stroke-width' : '2px'
})
;
curr.attr({
cx : curr.attr('init-cx'),
cy : curr.attr('init-cx')
});
})
;
d3.select('#drag').call(move);
});
对于D3 v4(可能适用于v5和v6),您可以确定节点在dragged
事件期间的位置,并查看它是否与其原始位置不同。假设没有,则永远不会调用alphaTarget
。
例如:
function dragstarted(d) {
// if (!d3.event.active) simulation.alphaTarget(0.2).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
if (d3.event.active && (d.fy != d3.event.y || d.fx != d3.event.x)) {
simulation.alphaTarget(0.5).restart();
}
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
相关文章:
- 如何在使用mapbox LeafLet拖动标记时获取标记拖动事件
- 可以'如果我隐藏某些日期,则不要在FullCalendar中拖动事件
- 如何删除可拖动组中某个元素上的拖动事件
- 如何在D3中添加一个强制拖动事件,并使节点停留在我离开它的地方
- 如何覆盖jQuery-ui-sortable的拖动事件
- 为什么clientX在上次拖动事件时重置为0,以及如何解决它
- 拖动事件后更新jQuery中jqxListBox的列表
- Javascript 拖动事件不起作用
- Jquery UI:可拖动拖动事件不起作用
- 使用锤子.js拖动事件
- 如何在鼠标单击时设置可拖动事件
- 如何捕获拖动事件的任何结束
- 谷歌地图可编辑多边形过滤器 从set_at事件中拖动事件
- 使用 RxJS Observable 更改拖动事件上的 css 类
- 确定从拖动和拖动事件中拖动的内容
- 是否可以以编程方式触发点击/拖动事件以启动轮播移动
- Google 地图拖动事件不会捕获中心更改,直到拖动在 Chrome 设备模式下结束
- 在 Firefox 或 IE 中未触发的拖动事件
- jQuery mousedown() 函数无法在拖动事件上触发
- 在拖动事件期间禁用链接 Javascript