2017-08-14 82 views
10

我在Chrome上遇到触摸屏过度滚动问题。为SVG元素动态禁用触摸动作(overscroll)

我有它时许SVG元素,其中包含了一些形状的文件,说一个矩形:

enter image description here

现在,我想使矩形可拖动,这意味着我要禁用通过设置它的样式属性touch-action: none,对各自的<rect>元素执行各种触摸操作。

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

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

enter image description here

,如果我有一个HTML元素,而不是一个SVG元素,设置touch-action: none会做这项工作。 SVG元素上的相同内容失败。

从技术上讲,这可以通过对任一document.body设置touch-action: none或包裹整个SVG成<div>元件与touch-action: none组来解决。

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

作为一个解决方案,我曾尝试动态地设置touch-action: nonedocument: bodypointerdown事件上的一个矩形出现。

// 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"; 
}); 

不幸的是,这并没有帮助。身体上的样式被设置,下一次我尝试拖动矩形时,它会按预期工作(因为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"; 
 
});
<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>


更新:看起来像上touchstart事件中使用preventDefault()开了窍。

但是,同时使用现代pointerdown和传统touchstart似乎是错误的。这看起来像是Chrome 60中的一个错误。如果任何人都可以证实,那会很好。

+0

应该只具有触摸屏的工作的例子吗?我无法移动您的矩形。顺便说一下,你是否尝试过'preventDefault'事件,当矩形被按下时触发平底锅? – lilezek

+0

是的,它仅适用于触摸屏。而且,为了简单起见,实际移动矩形的代码并不存在,因为它超出了这一点。另外,是的,我确实尝试了'preventDefault()' - 感谢提醒我,我会更新问题 – martynasma

+0

您在哪些事件中_prevented_? – lilezek

回答

2

我认为这将是足以防止touchstart

window.addEventListener("touchstart", function(e) { 
    // Determine wether or not you are panning from rectangle: 
    if (e.target ....) 
     e.preventDefault(); 
}); 
+0

没有这种事件'pandown',或者我错过了什么吗? – martynasma

+0

对不起,我错了。pandown是一个离子事件。你必须使用touchstart。 – lilezek

+0

Gotcha。更新了我的问题,看起来像touchstart这样做。然而,使用这两个事件仅仅是为了解决Chrome的功能,或者它是一个bug,似乎是错误的吗? – martynasma