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:
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.
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.
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
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
W jakich zdarzeniach się wycofałeś? – lilezek