d3.behavior.zoom禁用双击

时间:2015-03-18 17:11:10

标签: javascript d3.js

我不确定这是否可行,但我想在双击时禁用缩放行为,并在平板电脑上使用时保持缩放缩放行为。我想将此事件用于其他功能。 如果我禁用“touchstart.zoom”事件,我将失去整个缩放功能。

1 个答案:

答案 0 :(得分:0)

D3控制您选择使用touchstart.zoom缩放的元素上的d3.behavior.zoom()()事件。您不能简单地替换此处理程序并有条件地调用原始D3处理程序,因为它的部分算法会添加并删除此处理程序,因此您的覆盖将被覆盖。

但是,您可以进一步向上游捕获此事件,并有条件地允许它以缩放行为传播到元素。为此,您需要将处理程序添加到子元素,以便它将冒泡到缩放元素。例如:

<g class="zoom_area">  <-- Element you called D3 zoom behaviour on
  <rect width=... height=... style="visibility:hidden; pointer-events:all" class="background">
    // Background rect that will catch all touch events missed by your elements
  </rect>
  <g class="content"> <-- Container for your elements
    ...  <-- Your SVG content
  </g>
</g>

设置正常的D3缩放行为:

var zoomer = d3.behavior.zoom();
zoomer(d3.select('g.zoom_area'));

然后设置双击覆盖:

var last_touch_time = undefined;
var touchstart = function() {
    var touch_time = d3.eent.timeStamp;
    if (touch_time-last_touch_time < 500 and d3.event.touches.length===1) {
        d3.event.stopPropagation();
        last_touch_time = undefined;
    }
    last_touch_time = touch_time;
};
d3.select('.background_rect').on('touchstart.zoom', touchstart);
d3.select('.content').on('touchstart.zoom', touchstart);

这是一个替代版本,它只会检测点击发生在类似位置的快速触摸。缺点是不同位置的快速点击仍然可以放大。好处是快速合法的平移/缩放手势仍然有效。

var last_touch_event = undefined;
var touchstart = function() {
    if (last_touch_event && d3.event.touches.length===1 &&
        d3.event.timeStamp - last_touch_event.timeStamp < 500 &&
        Math.abs(d3.event.touches[0].screenX-last_touch_event.touches[0].screenX) < 10 &&
        Math.abs(d3.event.touches[0].screenY-last_touch_event.touches[0].screenY) < 10) {
        d3.event.stopPropagation();
        last_touch_time = undefined;
    }
    last_touch_event = d3.event;
};
d3.select('.background_rect').on('touchstart.zoom', touchstart);
d3.select('.content').on('touchstart.zoom', touchstart);