如何删除可拖动组中一个元素的拖动事件?
How can I remove drag event on one element in a draggable group?
我有一个可拖动组,该组中的一个元素调用了点击事件。现在我想删除该元素上的拖动事件。参见 http://jsfiddle.net/gLvyouct/1/
我试过这些方法:
添加circle.call(drag).on(".drag", null);
不工作,我不知道为什么。
只在矩形上调用拖动事件
会影响拖动事件的流畅度。拖动时元素会晃动。
在拖动行为的定义中if (d3.event.sourceEvent.target.nodeName == "circle") return;
不工作。当你的鼠标在圆的边缘时,组仍然移动。
这是一个棘手的问题,因为如果将拖动事件绑定到rect
,然后移动矩形所属的g
,则计算出的dx
和[= d3.event
对象中的 15=] 值在每次事件触发后都会被打乱,因为这些计算值已转换为拖动行为绑定到的元素的局部坐标系。所以,我们可以自己做一些类似的事情来解决这个问题。这里的技巧是知道我们真的只需要弄清楚拖动操作期间鼠标 x
和 y
位置的变化。 d3 使这些在 d3.event
对象的 sourceEvent
属性 中可用。
所以使用d3.event
对象中的底层sourceEvent
来获取clientX
和clientY
位置,只计算最后一个值和当前值之间的差值,它将告诉您 translate
g
元素需要多远。您还需要初始化要比较的值,这样您就不会在开始时随机跳转。幸运的是,我们可以使用 dragstart
事件来做到这一点。
一旦我们弄明白了,我们就可以将 drag
处理程序绑定到 rect
,我们应该可以开始了。
这是一个完全按照我所描述的方式进行操作的示例。
var g = d3.select("#mysvg").append("g");
var rect = g.append("rect").attr("height", 100).attr("width", 100);
var circle = g.append("circle").attr("cx", 200).attr("cy", 200).attr("r", 50).attr("fill", "black");
var transX = 0, transY = 0;
var lastX = 0, lastY = 0;
var drag = d3.behavior.drag().on("drag", function() {
transX += d3.event.sourceEvent.clientX - lastX;
transY += d3.event.sourceEvent.clientY - lastY;
g.attr("transform", "translate(" + transX + "," + transY + ")");
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
}).on("dragstart", function() {
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
});
rect.call(drag);
circle.on("click", function() {
var now_color = d3.select(this).attr("fill");
if (now_color == "black")
d3.select(this).attr("fill", "green");
else
d3.select(this).attr("fill", "black");
});
//circle.call(drag).on(".drag", null);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id="mysvg" height="800" width="800"></svg>
我有一个可拖动组,该组中的一个元素调用了点击事件。现在我想删除该元素上的拖动事件。参见 http://jsfiddle.net/gLvyouct/1/
我试过这些方法:
添加
circle.call(drag).on(".drag", null);
不工作,我不知道为什么。
只在矩形上调用拖动事件
会影响拖动事件的流畅度。拖动时元素会晃动。
在拖动行为的定义中
if (d3.event.sourceEvent.target.nodeName == "circle") return;
不工作。当你的鼠标在圆的边缘时,组仍然移动。
这是一个棘手的问题,因为如果将拖动事件绑定到rect
,然后移动矩形所属的g
,则计算出的dx
和[= d3.event
对象中的 15=] 值在每次事件触发后都会被打乱,因为这些计算值已转换为拖动行为绑定到的元素的局部坐标系。所以,我们可以自己做一些类似的事情来解决这个问题。这里的技巧是知道我们真的只需要弄清楚拖动操作期间鼠标 x
和 y
位置的变化。 d3 使这些在 d3.event
对象的 sourceEvent
属性 中可用。
所以使用d3.event
对象中的底层sourceEvent
来获取clientX
和clientY
位置,只计算最后一个值和当前值之间的差值,它将告诉您 translate
g
元素需要多远。您还需要初始化要比较的值,这样您就不会在开始时随机跳转。幸运的是,我们可以使用 dragstart
事件来做到这一点。
一旦我们弄明白了,我们就可以将 drag
处理程序绑定到 rect
,我们应该可以开始了。
这是一个完全按照我所描述的方式进行操作的示例。
var g = d3.select("#mysvg").append("g");
var rect = g.append("rect").attr("height", 100).attr("width", 100);
var circle = g.append("circle").attr("cx", 200).attr("cy", 200).attr("r", 50).attr("fill", "black");
var transX = 0, transY = 0;
var lastX = 0, lastY = 0;
var drag = d3.behavior.drag().on("drag", function() {
transX += d3.event.sourceEvent.clientX - lastX;
transY += d3.event.sourceEvent.clientY - lastY;
g.attr("transform", "translate(" + transX + "," + transY + ")");
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
}).on("dragstart", function() {
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
});
rect.call(drag);
circle.on("click", function() {
var now_color = d3.select(this).attr("fill");
if (now_color == "black")
d3.select(this).attr("fill", "green");
else
d3.select(this).attr("fill", "black");
});
//circle.call(drag).on(".drag", null);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id="mysvg" height="800" width="800"></svg>