如何丢弃d3v4拖动事件?

时间:2017-03-16 19:47:47

标签: javascript d3.js svg

我试图用d3和SVG构建一个可拖动的对象。 "目标" object是一个包含" rect"的SVG G元素。作为背景,SVG G元素作为具有点击事件(如网格)的孩子。

我想丢弃从起点拖动点​​开始的距离小于11的事件;因为"目标"对象具有在拖动距离太短时必须接收单击事件的子项。

我试图回归' true'或者' false'内部'拖动'用于控制此事件何时有效的函数事件;但它没有用。

var x1 =0, y1 =0;
target.call(d3.drag()
    .on("start", function () {
        x1 =d3.event.x;
        y1 =d3.event.y;
        return true;
    })
    .on("drag", function () {
        var x2 = d3.event.x;
        var y2 = d3.event.y;
        var x = x2 - x1;
        var y = y2 - y1;
        var d2 = x * x + y * y;
        var distance = Math.sqrt(d2);
        return distance > 10;
    }).on("end", function () {
        console.log("end");
    })
);

现在,使用拖动,我发现了另一个问题: 单击时刻鼠标上的一点移动会导致拖动事件而不是单击事件。

有没有办法解决这个问题而不执行类似假冒'点击?

1 个答案:

答案 0 :(得分:0)

我想我的代码片段会做你想要的,尽管不是太复杂。请注意,除非鼠标移动超过阈值,否则不会禁止单击。希望能使本质明确。灵感来自this github issue的讨论。

var target = d3.select('#test');
var x1 =0, y1 =0;
var threshold = 40;
var distanceReached = false;
target.call(d3.drag()
    .on("start", function () {
        x1 =d3.event.x;
        y1 =d3.event.y;
        distanceReached = false;
    })
    .on("drag", function () {
        var x2 = d3.event.x;
        var y2 = d3.event.y;
        var x = x2 - x1;
        var y = y2 - y1;
        var d2 = x * x + y * y;
        var distance = Math.sqrt(d2);
        distanceReached = distance > threshold;
        if (distanceReached) {
          target
            .style('left', x2 + 'px')
            .style('top',  y2 + 'px');
        }
    }).on("end", function () {
        if (distanceReached) {
          console.log('drag');
        } else {
          d3.select(window).on('click.drag', null);
          console.log('no drag');
        }
    })
);
target.on('click', function() {
  console.log('click');
});
#test { background:red; position:absolute; height:40px; width:40px; }
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id='test' />