动态禁用SVG元素的触摸操作(过度滚动)

mar*_*sma 10 javascript css svg google-chrome touch

我在Chrome上触摸屏过度滚动时遇到问题.

我有一个包含SVG元素的文档,其中包含一些形状,比如一个矩形:

在此输入图像描述

现在,我想使矩形可拖动,这意味着我想<rect>通过设置它的样式属性来禁用相应元素上的各种触摸操作touch-action: none.

这适用于所有桌面浏览器,Chrome除外.在Chrome上,当我触摸并移动一个矩形时,浏览器的过度滚动功能就会启动.这会导致浏览器窗口笨拙地移动,以及我在矩形上设置的所有指针事件都被取消.

即pointermove注册了几分之一秒,然后当过度滚动开始时它就会停止.pointerup即使触摸被释放也不会被调用.

在此输入图像描述

现在,如果我有一个HTML元素而不是一个SVG元素,那么设置touch-action: none就可以了.SVG元素上的相同内容失败.

从技术上讲,这可以通过两种设置来解决touch-action: none上document.body或包裹整个SVG成<div>与元素touch-action: none集.

不幸的是,这对我来说不是一个选项,因为我需要文档(以及围绕矩形的SVG的其余部分)来保留其所有原始触摸手势,除非直接在矩形上.

作为一种解决方案,我确实尝试在矩形touch-action: none上document: body发生pointerdown事件时动态设置.

// Get element
var o = document.getElementById( "test" );

// disable touch action on press of the SVG element
o.addEventListener( "pointerdown", function(e) {
  document.body.style.touchAction = "none";
} );

// re-enable touch action when released
o.addEventListener( "pointerup", function(e) {
  document.body.style.touchAction = "auto";
} );
Run Code Online (Sandbox Code Playgroud)

不幸的是,这没有帮助.身体上的样式被设置,下次我尝试拖动矩形时,它按预期工作(因为pointerup事件永远不会被执行),这次不是.

添加preventDefault()到事件处理程序也没有任何效果.

如果有相似经验的人可以分享解决方案,我将不胜感激.

这是上面的一个实例.

// Get element
var o = document.getElementById( "test" );

// disable touch action on press of the SVG element
o.addEventListener( "pointerdown", function(e) {
  document.body.style.touchAction = "none";
} );

// re-enable touch action when released
o.addEventListener( "pointerup", function(e) {
  document.body.style.touchAction = "auto";
} );
Run Code Online (Sandbox Code Playgroud)
<svg id="test" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: 300px; height: 300px; border: 1px solid #eee;">
  <g transform="translate(50,50)">
    <rect fill="#00fff0" width="200" height="200" style="touch-action: none;"></rect>
  </g>
</svg>
Run Code Online (Sandbox Code Playgroud)


更新:看起来像preventDefault()在touchstart事件上使用诀窍.

然而,这似乎是错误的使用既现代pointerdown和传统touchstart在同一时间.这似乎是Chrome 60中的一个错误.如果有人能够确认,那就太好了.

lil*_*zek 3

我认为通过防止以下情况就足够了touchstart:

window.addEventListener( "touchstart", function(e) {
  // Determine wether or not you are panning from rectangle:
  if (e.target ....)
      e.preventDefault();
} );
Run Code Online (Sandbox Code Playgroud)