按住 Ctrl 键拖动时出错

Acy*_*Acy 4 javascript d3.js

我制作了两个片段,相同的代码,一个在JSFiddle 中,一个作为 Stack Snippet(见下文)。出于某种原因,Ctrl键 + 拖动会产生不同的结果。

如果我按住Ctrl键,JSFiddle 不会触发我的拖动事件,但 Stack Snippet 会。有人可以尝试运行这些吗?我以为这是浏览器或计算机问题,但也许不是。

var svg = d3.select('svg');

var drag = d3
      .drag()
      .on("start", function() {
        console.log("start");
      })
      .on("drag", function() {
        console.log("dragging");
      })
      .on("end", function() {
        console.log("eneded");
      });

svg.append("g").call(drag).append("circle").attr("cx", 10).attr("cy", 10).attr("r", 8)
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.2.0/d3.min.js"></script>
<svg></svg>
Run Code Online (Sandbox Code Playgroud)

alt*_*lus 6

从 D3 版本5.10.0(由 d3-drag 模块版本1.2.4修复 GitHub 问题#62引入)起,通过Ctrl按下键触发的事件被过滤掉,因为在某些情况下,Ctrl+click 应该打开上下文菜单。drag.filter()您涵盖的文档:

过滤器([过滤器])<>

如果过滤器指定,设置过滤器到指定的函数,并返回拖拽行为。如果未指定过滤器,则返回当前过滤器,默认为:

function filter() {
  return !d3.event.ctrlKey && !d3.event.button;
}
Run Code Online (Sandbox Code Playgroud)

如果过滤器返回 falsey,则忽略启动事件并且不启动任何拖动手势。因此,过滤器确定忽略哪些输入事件;默认过滤器会忽略辅助按钮上的 mousedown 事件,因为这些按钮通常用于其他目的,例如上下文菜单。

如您所见,这将忽略任何涉及Ctrl按键被按下的事件。但是,您问题中的代码段使用 D3 v5.2.0,它尚未实现上述更改,因此也使用Ctrl密钥侦听事件。

要包含这些事件,您可以轻松提供自己的过滤器,它可能只是!d3.event.ctrlKey从原始过滤器中删除部分:

.filter(function() { 
  return !d3.event.button;
})
Run Code Online (Sandbox Code Playgroud)

看看下面的工作演示:

function filter() {
  return !d3.event.ctrlKey && !d3.event.button;
}
Run Code Online (Sandbox Code Playgroud)
.filter(function() { 
  return !d3.event.button;
})
Run Code Online (Sandbox Code Playgroud)

  • 我将 d3 版本 5.7 与 Angular 一起使用,当我升级到 Angular 8 时,ctrl + 拖动停止工作。我没有升级d3。添加此过滤器并解决了问题。谢谢! (2认同)