即使鼠标不移动,D3 'Drag' 事件也会触发

Posted

技术标签:

【中文标题】即使鼠标不移动,D3 \'Drag\' 事件也会触发【英文标题】:D3 'Drag' event fires even when mouse doesn't move即使鼠标不移动,D3 'Drag' 事件也会触发 【发布时间】:2018-08-08 17:18:16 【问题描述】:

我注意到当我使用d3.drag().on('drag',...) 时,即使鼠标没有移动,它也会触发。使用下面的代码 sn-p(我从 this question 提取),如果我简单地单击并释放,我仍然会在控制台中看到 drag event 1

这是一个问题,因为我希望能够区分 dblclick 和拖动。我查看了this post 和this one,但无法让这些解决方案发挥作用(可能是因为这些是旧答案,而我使用的是 D3 v4)。我确实注意到在one of the answers 中的fiddle 中,它显示了相同的问题:点击事件和拖动事件。

我认为drag 事件只有在鼠标移动时才会被触发,然后我可以使用它来设置一个标记,将其标记为拖动,而不是双击。但是,如果在鼠标按下时触发拖动,这将不起作用。

非常愿意接受有关此建议的建议以及对 drag 为何如此行事的解释。我意识到这取决于浏览器,所以我运行的是 Chrome 64。

var count = 0;
d3.select("svg").call(d3.drag().on("start", function() 
  console.log("drag started")
).on("drag", function() 
  ++count; 
  console.log("drag event " + count)
).on("end", function() 
  count = 0;
  console.log("drag ended")
))
.as-console-wrapper  max-height: 20% !important;
svg 
  border: 1px solid black;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

【问题讨论】:

【参考方案1】:

所以d3.drag 有一个可以调用的clickDistance() 函数。这允许在触发拖动事件之前 mousedownmouseup 之间存在容差,这很可能是您正在寻找的。​​p>

const drag = d3.drag()
               .clickDistance(10)
               .on("start", () =>  console.log("drag started"); )
               .on("drag", () =>  console.log(`moved by $d3.event.dx,$d3.event.dy`); );

发生这种情况通常是因为您实际上在mousedownmouseup 之间稍微移动了鼠标,但只是非常轻微。我今天一直在看类似的东西,大概有 25% 的时间是我不小心移动鼠标(使用触摸时问题变得更糟)。

还要注意,因为您并没有真正提到它,但是您可以订阅 dblclick 事件。请注意,使用 dblclick 时的事件顺序如下所示(不禁止点击):

点击 点击 dblclick

【讨论】:

【参考方案2】:

我确实想出了以下解决问题的方法。基本上只需在拖动start 上保存鼠标位置,然后检查鼠标是否在拖动drag 上移动。

虽然这可行,但我有点假设 drag 已经在做类似的事情,或者会有更清洁的解决方案。很想知道是否有人有更好的东西!

var count = 0;
var dragStartPos = ;

d3.select("svg").call(d3.drag().on("start", function() 
  console.log("drag started")
  dragStartPos.x = d3.event.x;
  dragStartPos.y = d3.event.y;
).on("drag", function() 
  if(d3.event.x != dragStartPos.x ||
    	d3.event.y != dragStartPos.y) 
      ++count; 
      console.log("drag event " + count)
  
).on("end", function() 
  count = 0;
  console.log("drag ended")
))
.as-console-wrapper  max-height: 20% !important;
svg 
  border: 1px solid black;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

【讨论】:

【参考方案3】:

对不起,这是一个答案,我还没有足够的代表发表评论。

我没有看到d3.drag().on('drag',...) 在不移动鼠标的情况下被解雇。我在 mousedown 上收到 start 事件,在 mouseup 上收到 end 事件,drag 事件仅在实际拖动时触发。这是迄今为止我尝试过的所有浏览器(Chrome 63、FF 58、IE11)上的行为。这似乎与d3.drag API Reference 内联

【讨论】:

它实际上对我来说通常是这样工作的,但有时它会偏离并开始注册拖动事件,即使没有鼠标移动。我想这可能与鼠标有关,但我已经通过与触控板完全分开的点击进行了尝试(因此没有发生任何移动),但我仍然明白。但同样,这只会在某些时候发生。很奇怪的行为

以上是关于即使鼠标不移动,D3 'Drag' 事件也会触发的主要内容,如果未能解决你的问题,请参考以下文章

javascript --- 鼠标事件

用d3.behavior.drag拖拽的时候为啥svg图是默认的左上角跟随鼠标的移动吗

即使拦截鼠标事件,Qt 窗口也会移动

html5拖动元素会触发哪些事件

d3 - 触发鼠标悬停事件

js 鼠标移入触发事件。多次触发。