如何删除可拖动组中某个元素上的拖动事件

How can I remove drag event on one element in a draggable group?

本文关键字:拖动 元素 事件 删除 何删除      更新时间:2023-09-26

我有一个可拖动的组,该组中的一个元素调用了click event。现在我想删除该元素上的拖动事件。看见http://jsfiddle.net/gLvyouct/1/

我尝试过这些方法:

  • 添加circle.call(drag).on(".drag", null);

    不工作,我不知道为什么。

  • 仅调用rects 上的拖动事件

    将影响拖拽事件的流畅性。图元在拖动时会发生抖动。

  • 在阻力行为定义中if (d3.event.sourceEvent.target.nodeName == "circle") return;

    不起作用。当鼠标位于圆的边缘时,该组仍在移动。

这是一个棘手的问题,因为如果将拖动事件绑定到rect,然后移动rect所属的g,则在每个事件触发后,d3.event对象中计算的dxdy值将被打乱,因为这些计算值已被转换到拖动行为绑定的元素的局部坐标系中。因此,我们可以自己做一些类似的事情来解决这个问题。这里的诀窍是,我们只需要计算出鼠标在拖动过程中xy位置的变化。并且d3使得这些在d3.event对象的sourceEvent属性中可用。

因此,使用d3.event对象中的底层sourceEvent来获得clientXclientY的位置,并计算上一个值和当前值之间的差,这将告诉您需要translateg元素的额外距离。你还需要初始化你要比较的值,这样你就不会在一开始就得到随机跳跃。幸运的是,我们可以使用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>