D3平移/缩放行为在移动Safari上不起作用 [英] D3 pan/zoom behaviors don't work on mobile Safari

查看:184
本文介绍了D3平移/缩放行为在移动Safari上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在iPhone上,D3的平移/缩放行为效果不佳.要查看此问题,请在iPhone上访问此页面: http://bl.ocks.org/mbostock/3892919

On an iPhone, D3's pan/zoom behaviors don't work very well. To see the problem, visit this page on an iPhone: http://bl.ocks.org/mbostock/3892919

平移时,整个浏览器窗口趋向于拖动.缩放时,iPhone本身通常会在页面上进行缩放,而不是D3元素捕获缩放事件.

When you pan, the whole browser window tends to get dragged around. When you zoom, the iPhone itself will often zoom on the page, instead of the D3 element catching the pinch event.

我正在使用D3 v3.5.17.在移动Safari以及iPhone上的Chrome上都会发生这种情况(但我们都知道那仍然只是Safari).

I'm using D3 v3.5.17. This happens on mobile Safari as well as Chrome on the iPhone (but we all know that's still just Safari).

在进一步调查中,似乎某些SVG元素(例如<rect><circle>)将正确捕获触摸事件,将其引导通过D3,并阻止移动浏览器对其做出响应.其他SVG元素(例如<svg><g>)将忽略触摸事件,并将它们冒泡到浏览器中.

On further investigation, it appears that certain SVG elements such as <rect> and <circle> will properly catch the touch events, direct them through D3, and prevent the mobile browser from responding to them. Other SVG elements, such as <svg> and <g>, will ignore the touch events and they will bubble up to the browser.

我尝试将touchmove处理程序附加到SVG元素,并使用event.preventDefault()尝试阻止浏览器接管事件.那是行不通的.

I've tried attaching a touchmove handler to the SVG element and using event.preventDefault() to try to keep the browser from taking over the event. That doesn't work.

我尝试从容器SVG之外的其他元素调用d3.behavior.zoom()...返回的函数.那也行不通.

I've tried calling the function returned by d3.behavior.zoom()... from different elements than the container SVG. That also doesn't work.

如何使整个SVG正确响应iOS浏览器上的触摸事件(拖动和挤压)?

How can I make the whole SVG respond properly to touch events (drag and pinch) on iOS browsers?

推荐答案

该解决方案原来很笨拙,但很简单:与<g>元素一起添加到父<svg>并通过D3缩放进行转换事件中,我附加了<rect>元素,并确保它收到与<g>元素相同的scale(...)转换值.这样做的结果是,我的SVG后面有一个大的不可见矩形,可以毫无问题地捕获移动Safari触摸事件.

The solution turned out to be hacky, but simple: alongside the <g> element that gets appended to the parent <svg> and is transformed by the D3 zoom event, I append a <rect> element and make sure that it receives the same scale(...) transform value as the <g> element. The upshot of this is that there is a big invisible rectangle behind my SVG that catches mobile Safari touch events without any trouble.

最终结果是这样的:

<svg>
  <rect fill="transparent" x="0" y="0" width="3000" height="1000" transform="scale(0.8)"></rect>
  <g transform="translate(900,38) scale(0.8)">
    <!-- My SVG drawing/chart/whatever -->
  </g>
</svg>

更好的解决方案是将单击处理程序附加到传统的HTML元素(例如<div>).我将其附加到包含整个SVG的<div>上,并且可以完美运行-不需要hacky看不见的<rect>.

An even better solution is to attach the click handler to a traditional HTML element like a <div>. I attached it to the <div> that contains the entire SVG and it works perfectly--no hacky invisible <rect>s required.

这篇关于D3平移/缩放行为在移动Safari上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆