javascript - 在 D3 v5 中以编程方式停止 dragmove 事件

标签 javascript vue.js d3.js vuejs2

在 Vue/D3 项目中,我需要对某些可拖动元素的移动位置设置一些限制。

这是 dragmove 处理程序的摘录:

dragmove: function(d, i, n) {     
    // Stop if the node crosses a border
    if (parseInt(n[i].getAttribute('x')) > 200) {
        this.drag.dragend(); 
    }
}

this.drag.dragend(); 取自 an older answer on Stackoverflow 。不幸的是,它在 D3 v5 中不起作用(this.drag.dragend 不是函数)。

这是我的 drag 变量:

drag: d3.drag()
        .on('drag', this.dragmove)
        .on('end', this.dragended),

有没有办法更新我的代码以使用更新版本的 D3?

最佳答案

您可以使用 d3.event.on 临时覆盖事件监听器。因此,要在拖动事件本身期间以编程方式中断拖动,我们可以使用:

d3.event.on("drag", null)
d3.event.on("end", null)

这会暂时删除分配给每个事件监听器的功能。 您会注意到我也删除了结束事件 - 否则它将继续监听鼠标松开,而不管是否将函数分配给“拖动”事件监听器。

此功能在 event.on 下的 d3-drag 中有描述:

event.on(typenames, [listener])

Equivalent to drag.on, but only applies to the current drag gesture. Before the drag gesture starts, a copy of the current drag event listeners is made. This copy is bound to the current drag gesture and modified by event.on. This is useful for temporary listeners that only receive events for the current drag gesture. (source)

在下面的示例中,拖动事件在圆碰到直线时暂时从圆中移除。调度自定义事件以指示拖动已以编程方式中断。记录所有事件 - 表明结束、拖动和中断事件按预期工作:

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

var drag = d3.drag()
  .on("drag", function() {
    log(); // to log events as they are triggered.
	
    var selection = d3.select(this);
      
    // Update the circle as normal (but don't let cx exceed the line visually):
    selection.attr("cx", d3.event.x > 300 ? 300 : d3.event.x)
      .attr("cy", d3.event.y);
	  
      // If event.x > 300, interrupt drag:
    if(d3.event.x > 300) {
      
    // Disable the drag events temporarily
      d3.event.on("drag", null)
      d3.event.on("end", null) 

      // Optionally trigger some alternative event 
      selection.dispatch("interrupted");
    }
	
  })
  .on("end", function() {
    log(); 
  })

var circle = svg.select("circle")
  .call(drag)
  .on("interrupted", function() {
    d3.select(this)
      .transition()
      .attr("fill","orange")
      .attr("cx",250)
      .transition()
      .attr("fill","steelblue");
 
    log();
  })	
  

function log() {
	console.log(d3.event.type);
}
.as-console-wrapper { max-height: 40% !important; }
circle { cursor: pointer ; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="300">
	<circle cx="100" cy="50" fill="steelblue" r="10"></circle>
	<line x1="305" x2="305" y1="0" y2="400" stroke-width="1" stroke="black"></line>
</svg>

关于javascript - 在 D3 v5 中以编程方式停止 dragmove 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58023831/

相关文章:

javascript - 如何检查参数是否为对象?

javascript - ExtJs 父子组件双向绑定(bind)

javascript - 对 vuejs-templates webpack-simple 代码片段感到困惑

vue.js - 推送路由(从 vueJS 迁移到 nuxtJS)

javascript - D3js 如何在 .enter 上下文中追加 2 个相同级别的 child

javascript - 如何将 .jpg 从 URI 加载到 Canvas ?

ASP.NET 中的 Javascript 仪表控件

vue.js - Vuejs动态添加子路由

D3.js v6.2 - 在监听器函数中获取数据索引 - selection.on ('click',监听器)

javascript - 使用 d3.js 不显示垂直条上的文本