如果用户单击d3.js中的回合,如何防止拖动? [英] How to prevent the drag if the user clicks the round in d3.js?
问题描述
我有group元素,有circle和rect元素.用户可以拖动组元素,因此rect和circle元素都将移动.一切正常.但是,如果用户单击circle元素,则需要防止拖动. JS小提琴
I have group element it has circle and rect elements. User can drag the group element, so both rect and circle element will move. It is working fine. But I need to prevent the drag if the user clicks on the circle element. JS Fiddle
const x = 100;
var y = 100;
var grid = d3.select("#svg-area");
var g = grid.append("g")
.attr("transform", `translate(${x},${y})`)
.call(d3.drag()
.on("drag", function() {
var x1 = d3.event.x - 30;
var y1 = d3.event.y - 10;
d3.select(this).attr("transform", "translate(" +
(x1) + "," + (y1) + ")")
}));
newNode(g);
function newNode(g, text) {
var textWid = 100;
console.log('wid ', textWid);
g.append("rect")
.attr("class", "new-nodes")
.attr("x", '10')
.attr("y", '0')
.attr("rx", '6')
.attr("ry", '6')
.attr("width", textWid)
.attr("height", '35')
.style("fill", "#8c259f")
.style("stroke", "#222")
.style("cursor", "move");
g.append("circle")
.attr("class", "new-nodes")
.attr("cx", '10')
.attr("cy", '17')
.attr("r", '6')
.style("fill", "#dedede")
.style("stroke", "#b2b0b0")
.style("cursor", "pointer")
.on("click", function(d) {
/* d3.event.preventDefault();
d3.event.stopPropagation();
*/
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>
推荐答案
最简单的方法(最接近您的代码的一种方法)是将 on("click"
更改为 on(当再次释放鼠标按钮时,将记录一个"click"事件.在此之前,将明显记录一个"mousedown"事件.
The simplest way - the one closest to your code - is to change on("click"
to on("mousedown"
. A "click" event is registered when the mouse button is released again. A "mousedown" event is clearly registered before that. And the mousedown event is the one that triggers "dragstart".
const x = 100;
var y = 100;
var grid = d3.select("#svg-area");
var g = grid.append("g")
.attr("transform", `translate(${x},${y})`)
.call(d3.drag()
.on("drag", function() {
var x1 = d3.event.x - 30;
var y1 = d3.event.y - 10;
d3.select(this).attr("transform", "translate(" +
(x1) + "," + (y1) + ")")
}));
newNode(g);
function newNode(g, text) {
var textWid = 100;
console.log('wid ', textWid);
g.append("rect")
.attr("class", "new-nodes")
.attr("x", '10')
.attr("y", '0')
.attr("rx", '6')
.attr("ry", '6')
.attr("width", textWid)
.attr("height", '35')
.style("fill", "#8c259f")
.style("stroke", "#222")
.style("cursor", "move");
g.append("circle")
.attr("class", "new-nodes")
.attr("cx", '10')
.attr("cy", '17')
.attr("r", '6')
.style("fill", "#dedede")
.style("stroke", "#b2b0b0")
.style("cursor", "pointer")
.on("mousedown", function(d) {
d3.event.preventDefault();
d3.event.stopPropagation();
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>
Alternatively, you could just move the event to the rectangle and use d3.drag().container
. Normally, d3.drag
calculates the distance between the event and the parent element. Now, we need the grandparent, because the parent (the g
element) is the thing we want to drag around.
我还更改了 g
元素以使用基准对象,因此您可以更轻松地移动它.
I also changed the g
element to use a datum object, so you can more easily move it.
var grid = d3.select("#svg-area");
var g = grid.append("g")
.datum({
x: 100,
y: 100
})
.attr("transform", function(d) {
return `translate(${d.x},${d.y})`;
});
newNode(g);
function newNode(g, text) {
var textWid = 100;
console.log('wid ', textWid);
g.append("rect")
.attr("class", "new-nodes")
.attr("x", '10')
.attr("y", '0')
.attr("rx", '6')
.attr("ry", '6')
.attr("width", textWid)
.attr("height", '35')
.style("fill", "#8c259f")
.style("stroke", "#222")
.style("cursor", "move")
.call(d3.drag()
.container(grid.node())
.on("drag", function() {
d3.select(this.parentNode)
.attr("transform", function(d) {
d.x += d3.event.dx;
d.y += d3.event.dy;
return `translate(${d.x},${d.y})`;
});
}));
g.append("circle")
.attr("class", "new-nodes")
.attr("cx", '10')
.attr("cy", '17')
.attr("r", '6')
.style("fill", "#dedede")
.style("stroke", "#b2b0b0")
.style("cursor", "pointer");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>
这篇关于如果用户单击d3.js中的回合,如何防止拖动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!