【问题标题】:d3.behavior.zoom disable double tap behaviourd3.behavior.zoom 禁用双击行为
【发布时间】:2013-11-28 15:01:38
【问题描述】:

我刚刚开始使用 D3,它具有为移动应用程序创建形状等的图形功能,并且我在桌面上的缩放效果很好,并设法通过以下操作消除了双击缩放行为这个答案:How to disable double click zoom for d3.behavior.zoom?

有没有办法为移动设备禁用它(双击)?双击缩放也停止触发形状上的双击事件,所以如果我不能禁用双击缩放,有没有办法确保所有事件都在双击时触发,而不是仅仅缩放(双击桌面的行为是否符合预期)?

非常感谢, 贝基

【问题讨论】:

  • 防止双击操作实际上很棘手,因为没有双击事件本身——D3 将前一个事件的时间与当前事件的时间进行比较以找出这一点。如果您不需要缩放,您是否考虑过 drag behaviour
  • 感谢您的回复。我确实需要缩放才能工作,但由于双击缩放行为,我无法在可缩放窗口内触发任何双击事件,所以我希望捏缩放工作,但双击缩放不能。一些 dragstart 和 e.PreventDefault 序列会有什么好处吗?
  • 通过查看缩放行为的来源,您实际上需要对其进行修改。在移动设备上,你得到的只是触摸事件,它自己会弄清楚实际发生了什么。显然你不能禁用触摸事件,这是你在这里唯一可以做的事情。

标签: javascript mobile d3.js


【解决方案1】:

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

if (d3.event.sourceEvent.touches.length == 1) 
    return

【讨论】:

    【解决方案2】:

    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 事件在双击时正常触发。

    【讨论】:

      猜你喜欢
      • 2015-05-21
      • 2012-07-31
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-12
      相关资源
      最近更新 更多