D3 v4 - d3.zoom()可以防止绑定除Window之外的某些事件

vsy*_*ync 5 javascript d3.js

无益的Github 讨论让我在这里提出这个问题:


更改为新的v4.0 D3之后,好像在使用d3.zoom() 块一些事件,如:

打电话给:
svg.call(d3.zoom()
     .scaleExtent([1, 40])
     .translateExtent([[-100, -100], [width + 90, height + 100]])
     .on("zoom", zoomed));
Run Code Online (Sandbox Code Playgroud) 然后这个:
document.querySelector('svg').addEventListener('mouseup', function(){ alert(1) })
Run Code Online (Sandbox Code Playgroud)

单击SVG上的任何位置时不会发出任何警报.


我真的希望这样做:

window.addEventListener("mouseup", function(e){
    if( [target or target parent is the specific SVG element] ){
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

因为这将mouseup在窗口上引入全局非命名空间事件(此技术似乎适用于该window对象),并且此事件可能会在其他位置删除,或者多次发生.(封装它并不容易,或者我根本不知道如何).

关于如何mouseup在SVG上捕获事件的更好的想法?


与我的另一个问题相关:事件捕获命名空间

演示页面


更新:

在Mark的回答的帮助下,这是工作演示

Mar*_*ark 4

仍然不确定我理解你的意图,但你可能从错误的角度来处理这个问题。无需尝试添加自己的事件,只需在缩放行为提供的事件范围内工作即可。缩放功能提供平移,其中 mousedown 开始平移(即缩放start事件),而 mouseup 结束平移(即缩放end事件)。因此,真正的问题是,如何区分平移和“单击”鼠标释放?为此,只需检查用户是否移动了鼠标:

svg.call(d3.zoom()
         .scaleExtent([1, 40])
         .translateExtent([[-100, -100], [width + 90, height + 100]])
         .on("start", zoomstart)
         .on("end", zoomend)
         .on("zoom", zoomed));

var mousePos = null;
function zoomstart(){
  mousePos = d3.mouse(this);
}

function zoomend(){
  var m = d3.mouse(this);
  if (mousePos[0] ===  m[0] && mousePos[1] === m[1]){
    alert('mouseup');
  }
}

function zoomed() {
  svg.attr("transform", d3.event.transform);
  gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
  gY.call(yAxis.scale(d3.event.transform.rescaleY(y)));
}
Run Code Online (Sandbox Code Playgroud)

更新小提琴