Javascript d3.behavior.zoom禁用双击行为

Javascript d3.behavior.zoom禁用双击行为,javascript,mobile,d3.js,Javascript,Mobile,D3.js,我刚刚开始学习D3,它的图形功能可以为移动应用程序创建形状等,我已经在桌面上使用了非常好的缩放功能,并通过以下回答成功地消除了双击缩放行为: 有没有一种方法可以禁用移动设备的双击功能?双击缩放也会阻止形状上的双击事件触发,因此,如果我无法禁用双击缩放,是否有办法确保所有事件在双击时触发,而不仅仅是桌面上的缩放双击按预期进行 非常感谢, Becky假设在移动设备上,缩放应该通过捏手势完成,您可以尝试检测缩放处理程序中的手指数,如下所示: if (d3.event.sourceEvent.touch

我刚刚开始学习D3,它的图形功能可以为移动应用程序创建形状等,我已经在桌面上使用了非常好的缩放功能,并通过以下回答成功地消除了双击缩放行为:

有没有一种方法可以禁用移动设备的双击功能?双击缩放也会阻止形状上的双击事件触发,因此,如果我无法禁用双击缩放,是否有办法确保所有事件在双击时触发,而不仅仅是桌面上的缩放双击按预期进行

非常感谢,
Becky

假设在移动设备上,缩放应该通过捏手势完成,您可以尝试检测缩放处理程序中的手指数,如下所示:

if (d3.event.sourceEvent.touches.length == 1) 
    return
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>
然后设置双击覆盖:

var last_touch_time = undefined;
var touchstart = function() {
    var touch_time = d3.event.timeStamp;
    if (touch_time-last_touch_time < 500 && d3.event.touches.length===1) {
        d3.event.stopPropagation();
        last_touch_time = undefined;
        return;
    }
    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);

通过这种方法,我看到dblclick事件被触发为双击的正常情况。

防止双击操作实际上很棘手,因为不存在这样的双击事件-D3将前一个事件的时间与当前事件的时间进行比较,以了解这一点。如果你不需要zoom,你考虑过了吗?谢谢你的回复。我确实需要缩放才能工作,但由于双击缩放行为,我无法在可缩放窗口内触发任何双击事件,因此我希望收缩缩放才能工作,但双击缩放不能。dragstart和e.PreventDefault的某些序列有什么好处吗?从缩放行为的来源来看,您实际上需要修改它。在手机上,你所能得到的只是触摸事件,它能自己弄清楚到底发生了什么。显然,你不能禁用触摸事件,这是你在这里唯一能做的事情。
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);