Wyłącz opcję podwójnego dotknięcia „powiększenia” w przeglądarce na urządzeniach dotykowych

112

Chcę wyłączyć ten zoom double-tap funkcjonalności na określonych elementów w przeglądarce (na urządzeniach dotykowych), bez wyłączania wszystkich funkcji zoom .

Na przykład: jeden element można stuknąć wiele razy, aby coś się wydarzyło. Działa to dobrze w przeglądarkach na komputerze (zgodnie z oczekiwaniami), ale w przeglądarkach urządzeń dotykowych zostanie powiększone.

Wouter Konecny
źródło
Chociaż nie do powiększania, ale oto kilka innych, niezbędnych - `-webkit-touch-callout: none; -webkit-text-size-adjust: brak; -webkit-user-select: brak;
Udayraj Deshmukh

Odpowiedzi:

99

Uwaga (stan na 2020-08-04): to rozwiązanie nie działa w iOS Safari v12 +. Zaktualizuję tę odpowiedź i usunę tę notatkę, gdy znajdę jasne rozwiązanie, które obejmuje iOS Safari.

Tylko rozwiązanie CSS

Dodaj touch-action: manipulationdo dowolnego elementu, dla którego chcesz wyłączyć powiększanie podwójnym dotknięciem, tak jak w przypadku następującej disable-dbl-tap-zoomklasy:

.disable-dbl-tap-zoom {
  touch-action: manipulation;
}

Z touch-actiondokumentacji (wyróżnienie moje):

manipulacja

Włącz przesuwanie i szczypanie gestów powiększania, ale wyłącz dodatkowe niestandardowe gesty, takie jak dwukrotne dotknięcie, aby powiększyć .

Ta wartość działa na Androidzie i iOS.

Ross Allen
źródło
@SergoPasoevi, czy możesz stworzyć przykład, który nie działa? Używam tego rozwiązania na iOS 12 i działa na mnie.
Ross Allen
Widzę ten sam problem co @SergoPasoevi, nie działa na iOS 12
Trevor Jex
Pracował dla mnie na iOS 12!
KB2497,
2
jakie są wady owijania całego ciała dotykiem: manipulacja?
oygen
1
Nie działa na najnowszym iOS po dwukrotnym dotknięciu obrazu.
Adam Silver
54
<head>
<title>Site</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> 
etc...
</head>

Użyłem tego bardzo niedawno i działa dobrze na iPadzie. Nie testowałem na Androidzie ani innych urządzeniach (ponieważ strona będzie wyświetlana tylko na iPadzie).

Kablam
źródło
16
To wyłączy WSZYSTKIE funkcje zoomu, niestety to nie było moje pytanie. Chcę wyłączyć tylko określone elementy.
Wouter Konecny
Oi bzdury. Przeczytałem to na odwrót, poniosę porażkę. Przepraszam!
Kablam
5
A co z tym rozwiązaniem? To tylko iOS, ale być może można go dostosować? : gist.github.com/2047491
Kablam
2
@WouterKonecny ​​Jeśli usuniesz agenta użytkownika, sprawdź, czy powinien on działać na każdym urządzeniu obsługującym zdarzenie touchstart. Aby wykryć te urządzenia, możesz użyć czegoś takiego jak isEventSupported
nxt
4
Apple teraz oficjalnie to ignoruje. github.com/w3c/html/issues/602
catamphetamine
38

Wiem, że to może być stare, ale znalazłem rozwiązanie, które działało idealnie dla mnie. Nie ma potrzeby stosowania zwariowanych metatagów i zatrzymywania powiększania treści.

Nie jestem w 100% pewien, jak to jest na różnych urządzeniach, ale zadziałało dokładnie tak, jak chciałem.

$('.no-zoom').bind('touchend', function(e) {
  e.preventDefault();
  // Add your code here. 
  $(this).click();
  // This line still calls the standard click event, in case the user needs to interact with the element that is being clicked on, but still avoids zooming in cases of double clicking.
})

Spowoduje to po prostu wyłączenie normalnej funkcji stukania, a następnie ponowne wywołanie standardowego zdarzenia kliknięcia. Zapobiega to powiększaniu urządzenia mobilnego, ale poza tym działa normalnie.

EDYCJA: Zostało to teraz przetestowane i uruchomione w kilku aplikacjach na żywo. Wydaje się być w 100% między przeglądarkami i platformą. Powyższy kod powinien działać jako rozwiązanie kopiuj-wklej w większości przypadków, chyba że chcesz zachować niestandardowe zachowanie przed zdarzeniem kliknięcia.

Rockster160
źródło
prosta, ale świetna odpowiedź. nie ma potrzeby modyfikowania metatagów itp.
Benpresser
2
to wyłącza kliknięcia, nie sądzę, że to dobre rozwiązanie, przepraszam
Pixelomo
6
nie potrzebujesz do tego JS, możesz po prostu ustawić atrybut CSSpointer-events: none
Pixelomo
1
Dziękuję, że działało to idealnie przy obsłudze przycisków zwiększania / zmniejszania bez wyłączania powiększenia na całej stronie.
Ramón,
1
Jeśli dobrze to widzę, może się to nie powieść w pewnych sytuacjach, w których potrzebujesz zaufanych zdarzeń (na przykład kliknięcie na coś, co uruchamia pełny ekran lub inne eksperymentalne, jako yneed zaufane zdarzenia, co oznacza WYZWALANIE PRZEZ UŻYTKOWNIKA / OS)
Manuel Graf
29

Chciałem tylko poprawnie odpowiedzieć na moje pytanie, ponieważ niektórzy ludzie nie czytają komentarzy pod odpowiedzią. Więc oto jest:

(function($) {
  $.fn.nodoubletapzoom = function() {
      $(this).bind('touchstart', function preventZoom(e) {
        var t2 = e.timeStamp
          , t1 = $(this).data('lastTouch') || t2
          , dt = t2 - t1
          , fingers = e.originalEvent.touches.length;
        $(this).data('lastTouch', t2);
        if (!dt || dt > 500 || fingers > 1) return; // not double-tap

        e.preventDefault(); // double tap - prevent the zoom
        // also synthesize click events we just swallowed up
        $(this).trigger('click').trigger('click');
      });
  };
})(jQuery);

Nie napisałem tego, po prostu zmodyfikowałem. Znalazłem wersję tylko dla iOS tutaj: https://gist.github.com/2047491 (dzięki Kablam)

Wouter Konecny
źródło
1
To wydaje się nie działać, przynajmniej nie na SIII (z Androidem 4.0.4). Próbowałem połączyć dokument, treść, okno, *, bez kości.
Maksymalnie
Wypróbował mnie też, działa na Safari / iPadzie, Android Chrome, ale nie z domyślną przeglądarką Androida
Strae
2
jquery nie jest javascriptem, byłoby miło mieć przykład, jak to zrobić bez biblioteki
Martijn Scheffer
Szukam wersji innej niż jquery :-(
Timo
ponownie, jQuery nie jest javascriptem i nie należy go zachęcać, ponieważ nie działa dobrze z witrynami opartymi na bardziej nowoczesnych ideach, takich jak angular. przeczytaj pytanie
Martijn Scheffer
16

CSS, aby globalnie wyłączyć powiększanie podwójnym dotknięciem (na dowolnym elemencie):

  * {
      touch-action: manipulation;
  }

manipulacja

Włącz przesuwanie i szczypanie gestów powiększania, ale wyłącz dodatkowe niestandardowe gesty, takie jak dwukrotne dotknięcie, aby powiększyć.

Dzięki Ross, moja odpowiedź rozszerza jego: https://stackoverflow.com/a/53236027/9986657

Jan
źródło
1
To powinno być oznaczone jako odpowiedź. Próbowałem umieścić to tylko w html i body, ale nie działało w iOS 13.2. To działa.
R OMS
To nie działa samo w iOS 13, ale w połączeniu z tym kodem blokuje stuknij, aby całkowicie powiększyć aplikację React. document.getElementById('root').addEventListener('click', () => {})
Siergiej
Apple wyłączone dotknij, aby powiększyć ios13, jak możesz powiedzieć, że nie działa na iOS13?
oygen
15

Jeśli potrzebujesz wersji, która działa bez jQuery , zmodyfikowałem odpowiedź Woutera Konecnego (która również została stworzona przez zmodyfikowanie tego sedna przez Johana Sundströma ), aby używała waniliowego JavaScript.

function preventZoom(e) {
  var t2 = e.timeStamp;
  var t1 = e.currentTarget.dataset.lastTouch || t2;
  var dt = t2 - t1;
  var fingers = e.touches.length;
  e.currentTarget.dataset.lastTouch = t2;

  if (!dt || dt > 500 || fingers > 1) return; // not double-tap

  e.preventDefault();
  e.target.click();
}

Następnie dodaj procedurę obsługi zdarzeń, touchstartktóra wywołuje tę funkcję:

myButton.addEventListener('touchstart', preventZoom); 
Evrim Persembe
źródło
3
znakomity. chciałem tylko wspomnieć, że muszę dodać addEventListener, aby to wywołać. myButton.addEventListener('touchstart', preventZoom);
martin jakubik
11

Należy ustawić właściwość css touch-action, aby nonew sposób opisany w tej drugiej odpowiedzi https://stackoverflow.com/a/42288386/1128216

.disable-doubletap-to-zoom {
    touch-action: none;
}
Jonathan Morales Vélez
źródło
1
To działa ... ale co jeśli chcę wyłączyć powiększanie, ale zostawić inne zdarzenia dotykowe? Mam duży stół i to również wyłącza przewijanie.
FrenkyB
2
Jeśli chcesz tylko pozbyć się powiększenia za pomocą dwukrotnego dotknięcia, ustaw wartość na „akcja dotykowa: manipulacja;” To nadal pozwoli na przesuwanie i powiększanie przez szczypanie. Ważna uwaga: Pomaga to również pozbyć się przeglądarek opóźniających kliknięcie wprowadzonych w celu zaimplementowania powiększenia za pomocą podwójnego dotknięcia. zobacz developer.mozilla.org/en-US/docs/Web/CSS/touch-action
cschuff
Do jakiego tagu HTML należy dodać tę klasę?
Razvan Zamfir
Myślę, że możesz po prostu dodać to do dowolnego elementu, którego nie chcesz powiększać. Na przykład w moim przypadku nie chciałem, aby użytkownik powiększał jakąkolwiek część mojej strony, więc dodałem go do tagu body.
Jonathan Morales Vélez
2
* {
    -ms-touch-action: manipulation;
    touch-action: manipulation;
}

Wyłącz podwójne dotknięcie, aby powiększyć ekrany dotykowe. W zestawie przeglądarka internetowa.

Erçin Dedeoğlu
źródło
1

Proste zapobiec zachowanie domyślne click, dblclicklub touchendzdarzenia spowoduje wyłączenie funkcji zoom.

Jeśli masz już oddzwonienie na jedno z tych wydarzeń, po prostu zadzwoń do event.preventDefault().

William Grasel
źródło
1
To zadziałało dla mnie. Definiowałem własne zdarzenie Touchstart na przycisku i chciałem wyłączyć funkcję powiększania.
Rick Giuly
1

Jeśli jest ktoś taki jak ja, który doświadcza tego problemu podczas korzystania z Vue.js , wystarczy dodać .prevent :@click.prevent="someAction"

Sølve Tornøe
źródło
0

Zapobiegnie to dwukrotnemu powiększaniu elementów w „treści”, które można zmienić na dowolny inny selektor

$('body').bind('touchstart', function preventZoom(e){
            var t2 = e.timeStamp;
            var t1 = $(this).data('lastTouch') || t2;
            var dt = t2 - t1;
            var fingers = e.originalEvent.touches.length;
            $(this).data('lastTouch', t2);
            if (!dt || dt > 500 || fingers > 1){
                return; // not double-tap
            }
            e.preventDefault(); // double tap - prevent the zoom
            // also synthesize click events we just swallowed up
            $(e.target).trigger('click');

});

Ale to również uniemożliwiło wywołanie zdarzenia kliknięcia po wielokrotnym kliknięciu, więc musiałem powiązać inne zdarzenie, aby wywołać zdarzenia po wielu kliknięciach

$('.selector').bind('touchstart click', preventZoom(e) {    
    e.stopPropagation(); //stops propagation
    if(e.type == "touchstart") {
      // Handle touchstart event.
    } else if(e.type == "click") {
      // Handle click event.
    }
});

Na Touchstart dodałem kod, aby zapobiec powiększeniu i wywołać kliknięcie.

$('.selector').bind('touchstart, click', function preventZoom(e){
            e.stopPropagation(); //stops propagation
            if(e.type == "touchstart") {
                // Handle touchstart event.
                var t2 = e.timeStamp;
                var t1 = $(this).data('lastTouch') || t2;
                var dt = t2 - t1;
                var fingers = e.originalEvent.touches.length;
                $(this).data('lastTouch', t2);


                if (!dt || dt > 500 || fingers > 1){
                    return; // not double-tap
                }

                e.preventDefault(); // double tap - prevent the zoom
                // also synthesize click events we just swallowed up
                $(e.target).trigger('click');

            } else if(e.type == "click") {
                // Handle click event.
               "Put your events for click and touchstart here"
            }

 });
Dally S
źródło
-1

Zakładam, że mam <div>obszar kontenera wejściowego z tekstem, suwakami i przyciskami i chcę powstrzymać przypadkowe dwukrotne dotknięcie <div>. Poniższe informacje nie przeszkadzają w powiększaniu obszaru wprowadzania i nie dotyczą dwukrotnego dotknięcia i powiększania poza moim <div>obszarem. Istnieją różnice w zależności od aplikacji przeglądarki.

Właśnie tego spróbowałem.

(1) W przypadku przeglądarki Safari na iOS i Chrome na Androida i jest to metoda preferowana. Działa z wyjątkiem aplikacji internetowej na Samsunga, w której wyłącza podwójne dotknięcie nie na pełnym <div>, ale przynajmniej na elementach obsługujących dotknięcia. Zwraca return false, z wyjątkiem stanu texti rangedanych wejściowych.

$('selector of <div> input area').on('touchend',disabledoubletap);

function disabledoubletap(ev) {

    var preventok=$(ev.target).is('input[type=text],input[type=range]');

    if(preventok==false) return false; 
}

(2) Opcjonalnie dla wbudowanej aplikacji internetowej na Androida (5.1, Samsung), blokuje dwukrotne dotknięcie <div>, ale blokuje powiększanie <div>:

$('selector of <div> input area').on('touchstart touchend',disabledoubletap);

(3) W przypadku przeglądarki Chrome w systemie Android 5.1 w ogóle wyłącza podwójne stuknięcie, nie blokuje powiększania i nie powoduje dwukrotnego stuknięcia w innych przeglądarkach. Hamowanie podwójnego dotknięcia <meta name="viewport" ...>jest irytujące, ponieważ <meta name="viewport" ...>wydaje się dobrą praktyką.

<meta name="viewport" content="width=device-width, initial-scale=1, 
          maximum-scale=5, user-scalable=yes">
Piotr
źródło
-4

No to ruszamy

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

niepewny
źródło