【问题标题】:How to discard d3v4 drag events?如何丢弃 d3v4 拖动事件?
【发布时间】:2017-03-16 19:47:46
【问题描述】:

我正在尝试使用 d3 和 SVG 构建一个可拖动的对象。 “target”对象是一个 SVG G 元素,其中包含一个“rect”作为背景,SVG G 元素作为具有点击事件的子元素(如网格)。

我想丢弃距离起始拖动点的距离小于 11 的事件;因为“目标”对象的子对象在拖动距离太短时必须接收点击事件。

我试图在 'drag' 函数事件中返回 '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");
    })
);

现在,使用拖动,我发现了一个额外的问题: 单击时鼠标稍微移动会导致拖动事件而不是单击事件。

有什么方法可以在不执行“假”点击之类的操作的情况下解决问题?

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    我猜我的 sn-p 可以满足您的需求,尽管它并不太复杂。请注意,除非鼠标移动超过阈值,否则不会抑制单击。希望能说明本质。灵感来自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' />

    【讨论】:

    • 对不起,您的回答有效,但我在子对象中使用点击事件,而不是在“目标”对象中。我更新了我的问题以更清楚。
    • 我无法正确测试此代码。我清理了我的项目并再次尝试,现在它可以工作了。谢谢。
    • 您是否必须修改代码才能与子对象一起运行?
    • 不,我没有。无需执行更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多