d3.behaviour.zoom在仅使用一根手指时禁用触摸屏上的平移

Dan*_*isp 5 javascript d3.js

我有一个强制布局d3图表,我d3.behaviour.zoom用来启用缩放和平移.

这一切都很好但是因为我的图表在iPad上填满了屏幕,所以当我的触摸只是平移图表时,无法向下滚动页面.

我想在触摸设备上保持捏缩放行为.

是否可以在何时取消touchmove.zoom活动?d3.event.touches.length === 1

这只是禁用所有触摸交互 - 所以滚动很好,但我不能再缩放图表:

selection.call(zoom)
    .on('touchstart.zoom', null)
    .on('touchmove.zoom', null)
    .on('touchend.zoom', null);
Run Code Online (Sandbox Code Playgroud)

我也试过添加另一个touchmove监听器,如下所示:

selection.call(zoom)
    .on('touchmove', function () {
        if (d3.event.touches.length === 1) {
            d3.event.stopPropagation();
            // i've also tried d3.event.preventDefault() but it doesn't do anything         
        }
    });
Run Code Online (Sandbox Code Playgroud)

我不认为我可以touchmove在d3内访问默认的缩放监听器吗?我想知道我是否可以删除侦听器touchstart,然后touchend如果用户只使用一次触摸就重新绑定它.

And*_*rew 0

听起来您需要比使用内置事件更精细的事件控制。尝试创建一个处理标准事件并将其转换为自定义事件的对象(基于您选择的规则,例如仅 1 次触摸)。然后,您可以在 d3 调度机制的帮助下监听这些自定义事件的抛出。

Events = function() {

  // custom event set up using d3 dispatch
  var dispatch = d3.dispatch("drag", "drag2");

  //listen for standard event on containing DOM element
  var events = function (g) {
    //g is the container DOM element

    // register the standard events required
    g.on("touchmove", touchmove)

    return events;
  };

  //function that handles the touchmove standard event
  function touchmove(d,i) {

    //stop the default event going any further
    d3.event.stopPropagation();

    //depending on your conditions choose which custom event you trigger
    if(condition1)
    {
      dispatch.drag.call(d3.event.target, d, i);
    }
    else if(condition2)
    {
      dispatch.drag2.call(d3.event.target, d, i);
    }
  }

  //add events defined in d3 dispatch function to events object and return   
  return d3.rebind(events, dispatch, "on");
}
Run Code Online (Sandbox Code Playgroud)

在代码的其他位置创建事件对象并侦听其自定义事件:

events = new Events();

//Set the containing element the events object should be registering event listeners to
d3.select(container).call(events);

events.on("drag", function (d, i, position) {
    //do something here
})

events.on("drag2", function (d, i, position) {
    //do something else here
})
Run Code Online (Sandbox Code Playgroud)