用 d3.JS 拖动

dragend with d3.JS

我只是在摆弄我在各种在线示例中找到的代码。到目前为止一切正常,除了我无法触发拖动结束事件。目前我只是想在控制台上打印 'end' 但似乎没有任何效果。

  const drag_handler = d3
    .drag()
    .on("start", drag_start)
    .on("drag", drag_drag)
    .on("end", drag_end);

  function drag_start(event, d) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
    event.on("end", console.log("start"));
  }

  function drag_drag(event, d) {
    d.fx = event.x;
    d.fy = event.y;
    event.on("end", console.log("drag"));
  }

  function drag_end(event, d) {
    event.on("end", console.log("end"));
    event.on("start", console.log("end"));
    console.log("end");

    if (!event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }

  drag_handler(d3.select("circle"));

这里是 pen 的完整代码

简单的解决方案

目前你有三个拖拽功能(除了日志我已经删除了所有的东西):

  function drag_start(event, d) {
    event.on("end", console.log("start"));
  }

  function drag_drag(event, d) {
    event.on("end", console.log("drag"));
  }

  function drag_end(event, d) {
    event.on("end", console.log("end"));
    event.on("start", console.log("end"));
    console.log("end");
  }

如果您只想登录 start/end/drag,您应该使用:

  function drag_start(event, d) {
    console.log("start");
  }

  function drag_drag(event, d) {
    console.log("drag");
  }

  function drag_end(event, d) {
    console.log("end");
  }

为什么您的代码无法按预期工作:

Event.on

通过使用 event.on(),您可以为结束事件添加一个新的临时事件侦听器:

Changes to registered listeners via drag.on during a drag gesture do not affect the current drag gesture. Instead, you must use event.on, which also allows you to register temporary event listeners for the current drag gesture. (docs)

这会覆盖原来的结束事件,因为每个 start/end/drag 只能有一个听众,除非您为听众命名。

一般来说,您想要使用 event.on 的情况有限 - 不清楚您为什么要在这里使用它。

将函数传递给 .on()

在使用 event.on 时,您实际上并没有向它传递任何函数,您传递的是 console.log("string") 的 return 值 - 这是未定义的。例如,要获取事件监听函数,您可以使用:

 console.log(event.on("end"));

如果将此添加到拖动功能,您会看到它 returns undefined

最终你正在做的是执行 console.log() 记录一个值,然后将 undefined 分配为事件侦听器函数。因为你把你原来的事件监听函数换成了空的,当拖动结束事件发生时,什么也没有发生。

如果你真的想在这里简单地控制台记录一些东西,你可以使用:

event.on("end", function() {
     console.log("end")
});

这里我们传递一个函数给.on()而不是undefined。另见 .

但是,如果您最初只是将拖动结束事件设置为使用

,则不清楚为什么需要使用event.on()
 function drag_end() {
  console.log("end");
 })

如上面的简单解决方案。