2017-08-14 73 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