2017-08-14 12 views
10

Mam problem z przeskalowaniem ekranu dotykowego w przeglądarce Chrome.Dynamiczne wyłączanie dotykania (przewijanie) elementów SVG

Mam dokument z AM elementu SVG w nim, który zawiera jakiś kształt, powiedzmy prostokąt:

enter image description here

Teraz chcę zrobić prostokąt przeciągany, co oznacza, że ​​chcę, aby wyłączyć wszystkie rodzaje działań dotykowych na danym elemencie <rect>, ustawiając jego właściwość stylu touch-action: none.

Działa to dobrze we wszystkich przeglądarkach komputerowych, z wyjątkiem Chrome. W przeglądarce Chrome po dotknięciu i przesunięciu prostokąta następuje przewijanie w przeglądarce. To powoduje, że okno przeglądarki porusza się niezręcznie, a wszystkie zdarzenia wskaźnika, które ustawiłem w prostokącie, zostały anulowane.

tj. pointermove jest rejestrowany przez ułamek sekundy, a następnie zatrzymuje się po przeskoczeniu kopnięć. pointerup nigdy nie jest wywoływany, nawet po dotknięciu przycisku.

enter image description here

Teraz, gdybym miał element HTML zamiast element SVG, ustawienie touch-action: none by wykonać zadanie. To samo dotyczy elementu SVG.

technicznego punktu widzenia, mogą być albo ustalone touch-action: none na document.body lub owinięcie całe SVG do elementu <div> z touch-action: none zestawie.

Niestety, nie jest to opcja dla mnie, ponieważ potrzebuję dokumentu (i reszty otaczającego SVG), aby zachować wszystkie oryginalne gesty dotykowe, z wyjątkiem sytuacji, gdy znajduje się bezpośrednio na prostokącie.

Jako rozwiązanie, próbowałem ustawić dynamicznie touch-action: none na document: body, gdy zdarzenie wystąpi w prostokącie na 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"; 
}); 

Niestety, to nie pomaga. Styl na ciele zostaje ustawiony i następnym razem, gdy spróbuję przeciągnąć prostokąt, działa zgodnie z oczekiwaniami (ponieważ zdarzenie pointerup nigdy nie zostanie wykonane), ale nie tym razem.

Dodanie preventDefault() do programów obsługi zdarzeń również nie przynosi efektu.

Byłbym wdzięczny, gdyby ktoś, kto miał podobne doświadczenia, mógł dzielić się rozwiązaniem.

Oto przykładowy przykład na żywo.

// 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>


UPDATE: Wygląda na to, używając preventDefault() na imprezie touchstart załatwia sprawę.

Jednak wydaje się błędne użycie zarówno nowoczesny pointerdown i starszego touchstart w tym samym czasie. Wygląda to jak błąd w Chrome 60.Jeśli ktokolwiek mógłby to potwierdzić, byłoby wspaniale.

+0

jest przykład powinien pracować tylko z ekranów dotykowych? Nie mogę przesunąć twojego prostokąta. Przy okazji, czy próbowałeś 'preventDefault' wydarzenie, które uruchamia pan, gdy prostokąt jest wciśnięty? – lilezek

+0

Tak, dotyczy tylko ekranów dotykowych. I dla uproszczenia sake kod, aby właściwie przesunąć prostokąt, nie istnieje, ponieważ jest poza to punktem. Ponadto, tak, wypróbowałem 'preventDefault()' - dziękuję za przypomnienie mi, że zaktualizuję pytanie – martynasma

+0

W jakich zdarzeniach się wycofałeś? – lilezek

Odpowiedz

2

myślę, że to wystarczy, zapobiegając touchstart:

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

Nie ma takiego zdarzenia 'pandown', czy coś mi brakuje? – martynasma

+0

Przykro mi, myliłem się, pandown jest zdarzeniem jonowym Musisz użyć touchstart – lilezek

+0

Uaktualniono moje pytanie Wygląda na to, że touchstart rozwiązuje problem, ale wydaje mi się, że korzystanie z obu wydarzeń jest tak złe, aby obejść funkcję Chrome, czy też jest to błąd? – martynasma

Powiązane problemy