我刚刚掌握 D3 以及它为移动应用程序创建形状等的图形功能,并且我已经让缩放在桌面上运行良好,并设法按照以下答案删除双击缩放行为:如何禁用 d3.behavior.zoom 的双击缩放?
有没有办法为移动设备禁用它(双击)?双击缩放也会阻止触发形状上的双击事件,因此,如果我无法禁用双击缩放,有没有办法确保所有事件都触发双击而不仅仅是缩放(双击桌面的行为符合预期)?
非常感谢,贝基
假设在移动设备上应使用捏合手势进行缩放,则可以尝试在缩放处理程序中检测手指数,如下所示:
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>
设置正常的 D3 缩放行为:
var zoomer = d3.behavior.zoom();
zoomer(d3.select('g.zoom_area'));
然后设置双点触控覆盖:
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
事件。