Disabilita l'opzione "zoom" con doppio tocco nel browser sui dispositivi touch


112

Desidero disabilitare la funzionalità di zoom con doppio tocco su elementi specificati nel browser (su dispositivi touch), senza disabilitare tutte le funzionalità di zoom .

Ad esempio: un elemento può essere toccato più volte perché accada qualcosa. Funziona bene sui browser desktop (come previsto), ma sui browser dei dispositivi touch, si ingrandirà.


Anche se non per lo zoom, eccone alcuni altri essenziali - `-webkit-touch-callout: none; -webkit-text-size-Adjust: nessuno; -webkit-user-select: nessuno;
Udayraj Deshmukh

Risposte:


99

Nota (a partire da 2020-08-04): questa soluzione non sembra funzionare in iOS Safari v12 +. Aggiornerò questa risposta ed eliminerò questa nota una volta trovata una soluzione chiara che copre iOS Safari.

Soluzione solo CSS

Aggiungi touch-action: manipulationa qualsiasi elemento su cui desideri disabilitare lo zoom con doppio tocco, come con la seguente disable-dbl-tap-zoomclasse:

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

Dai touch-actiondocumenti (enfasi mia):

manipolazione

Abilita i gesti di panoramica e zoom con pizzico, ma disabilita i gesti aggiuntivi non standard come il doppio tocco per ingrandire .

Questo valore funziona su Android e su iOS.


@SergoPasoevi, puoi creare un esempio che non funziona? Sto usando questa soluzione per iOS 12 e funziona per me.
Ross Allen

Vedo lo stesso problema di @SergoPasoevi, non funziona su iOS 12
Trevor Jex

Ha funzionato per me su iOS 12!
KB2497

2
quali sono gli svantaggi di avvolgere tutto il tuo corpo con l'azione tattile: manipolazione?
oygen

1
Non funziona sull'ultimo iOS quando si tocca due volte un'immagine.
Adam Silver il

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>

L'ho usato di recente e funziona bene su iPad. Non sono stati testati su Android o altri dispositivi (perché il sito Web verrà visualizzato solo su iPad).


16
Ciò disabiliterà TUTTE le funzionalità di zoom, sfortunatamente non era la mia domanda. Voglio disabilitare solo gli elementi specificati.
Wouter Konecny

Oi merda. L'ho letto al contrario, il fallimento è su di me. Scusa!
Kablam

5
Che ne dici di questa soluzione? È solo iOS, ma forse modificabile? : gist.github.com/2047491
Kablam

2
@WouterKonecny ​​Se rimuovi il controllo useragent dovrebbe funzionare su qualsiasi dispositivo che supporti l'evento touchstart. Per rilevare quei dispositivi puoi usare qualcosa come isEventSupported
nxt

4
Apple ora lo ignora ufficialmente. github.com/w3c/html/issues/602
catamphetamine

38

So che potrebbe essere vecchio, ma ho trovato una soluzione che funzionava perfettamente per me. Non c'è bisogno di metatag pazzi e fermare lo zoom dei contenuti.

Non sono sicuro al 100% di quanto sia cross-device, ma ha funzionato esattamente come volevo.

$('.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.
})

Ciò disabiliterà semplicemente la normale funzione di tocco, quindi richiamerà nuovamente un evento clic standard. Ciò impedisce al dispositivo mobile di eseguire lo zoom, ma per il resto funziona normalmente.

EDIT: ora è stato testato nel tempo e in esecuzione in un paio di app live. Sembra essere cross-browser e piattaforma al 100%. Il codice sopra dovrebbe funzionare come una soluzione di copia-incolla per la maggior parte dei casi, a meno che non si desideri un comportamento personalizzato prima dell'evento clic.


risposta semplice ma ottima. non c'è bisogno di modificare meta tag o ecc.
Benchpresser

2
questo disabilita i clic, non credo sia una buona soluzione scusate
Pixelomo

6
non hai bisogno di JS per farlo, puoi semplicemente impostare l'attributo CSSpointer-events: none
Pixelomo

1
Grazie, ha funzionato perfettamente per la gestione dei pulsanti di incremento / decremento senza disabilitare lo zoom sull'intera pagina.
Ramón

1
Se lo vedo correttamente, potrebbe non funzionare in determinate situazioni in cui sono necessari eventi attendibili (ad esempio, fare clic su qc che attiva lo schermo intero o altri esperimenti, come gli eventi attendibili necessari che significa ATTIVATI DALL'UTENTE / OS)
Manuel Graf

29

Volevo solo rispondere correttamente alla mia domanda poiché alcune persone non leggono i commenti sotto una risposta. Quindi eccolo qui:

(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);

Non l'ho scritto, l'ho appena modificato. Ho trovato la versione solo per iOS qui: https://gist.github.com/2047491 (grazie Kablam)


1
Questo non sembra funzionare, almeno non su SIII (con Android 4.0.4). Ho provato a collegarmi a documento, corpo, finestra, *, nessun dado.
Max

Provato anche con me, funziona su safari / ipad, Android Chrome ma non con il browser predefinito di Android
Strae

2
jquery non è javascript, sarebbe bello avere un esempio di come farlo senza una libreria
Martijn Scheffer

Alla ricerca di una versione non jquery :-(
Timo

ancora una volta, jQuery non è javascript e non dovrebbe essere incoraggiato, poiché non funziona bene con i siti basati su idee più moderne come angular. leggi la domanda
Martijn Scheffer

15

CSS per disabilitare lo zoom con doppio tocco a livello globale (su qualsiasi elemento):

  * {
      touch-action: manipulation;
  }

manipolazione

Abilita i gesti di panoramica e zoom con pizzico, ma disabilita i gesti aggiuntivi non standard come il doppio tocco per ingrandire.

Grazie Ross, la mia risposta estende la sua: https://stackoverflow.com/a/53236027/9986657


1
Questo dovrebbe essere contrassegnato come risposta. Ho provato a metterlo solo su html e body ma non ha funzionato in iOS 13.2. Funziona.
R OMS

Questo non funziona su iOS 13 da solo, ma in combinazione con questo codice si blocca tocca per ingrandire completamente l'app React. document.getElementById('root').addEventListener('click', () => {})
Sergei

apple disabilitata tocca per ingrandire su ios13, come puoi dire che non funziona su iOS13?
oygen

15

Se hai bisogno di una versione che funzioni senza jQuery , ho modificato la risposta di Wouter Konecny (che è stata creata anche modificando questa sintesi da Johan Sundström ) per utilizzare JavaScript vanilla.

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();
}

Quindi aggiungi un gestore di eventi su touchstartche chiama questa funzione:

myButton.addEventListener('touchstart', preventZoom); 

3
brillante. volevo solo menzionare che avevo bisogno di aggiungere un addEventListener per chiamare questo. myButton.addEventListener('touchstart', preventZoom);
martin jakubik

11

È necessario impostare la proprietà css touch-actionper nonecome descritto in questa altra risposta https://stackoverflow.com/a/42288386/1128216

.disable-doubletap-to-zoom {
    touch-action: none;
}

1
Funziona ... ma cosa succede se voglio disabilitare lo zoom, ma lasciare altri eventi di tocco? Ho una grande tabella e questo disabilita anche lo scorrimento.
FrenkyB

2
Se vuoi eliminare solo lo zoom con doppio tocco, devi impostare il valore su "touch-action: manipulate;" Ciò consentirà comunque la panoramica e lo zoom con le dita. Nota importante: questo aiuta anche a sbarazzarsi dei browser con ritardo del clic introdotti per implementare lo zoom con doppio tocco. vedi developer.mozilla.org/en-US/docs/Web/CSS/touch-action
cschuff

Su quale tag HTML dovrebbe essere aggiunta questa classe?
Razvan Zamfir

Penso che tu possa semplicemente aggiungerlo a qualsiasi elemento che non vuoi usare per ingrandire. Ad esempio, nel mio caso non volevo che l'utente ingrandisse nessuna parte della mia pagina, quindi l'ho aggiunto al tag body.
Jonathan Morales Vélez

2
* {
    -ms-touch-action: manipulation;
    touch-action: manipulation;
}

Disattiva il doppio tocco per eseguire lo zoom sui touch screen. Internet Explorer incluso.


1

Semplice impedire il comportamento predefinito di click, dblclicko gli touchendeventi disabiliteranno la funzionalità di zoom.

Se hai già una richiamata per uno di questi eventi, chiama un event.preventDefault().


1
Questo ha funzionato per me. Stavo definendo il mio evento touchstart su un pulsante e volevo disabilitare la funzione di zoom.
Rick Giuly

1

Se c'è qualcuno come me che sta riscontrando questo problema usando Vue.js , semplicemente aggiungendo .prevent farà il trucco:@click.prevent="someAction"


0

Ciò impedirà lo zoom doppio tocco sugli elementi nel "corpo" che può essere modificato in qualsiasi altro selettore

$('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');

});

Ma questo ha anche impedito l'attivazione del mio evento clic quando cliccato più volte, quindi ho dovuto associare un altro evento per attivare gli eventi su più clic

$('.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.
    }
});

Su touchstart ho aggiunto il codice per impedire lo zoom e attivare un clic.

$('.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"
            }

 });

-1

Presumo di avere un'area <div>contenitore di input con testo, cursori e pulsanti al suo interno e voglio inibire i doppi tocchi accidentali in questo <div>. Quanto segue non inibisce lo zoom nell'area di input e non riguarda il doppio tocco e lo zoom al di fuori della mia <div>area. Ci sono variazioni a seconda dell'app del browser.

L'ho appena provato.

(1) Per Safari su iOS e Chrome su Android ed è il metodo preferito. Funziona ad eccezione delle app Internet su Samsung, dove disabilita i doppi tocchi non del tutto <div>, ma almeno sugli elementi che gestiscono i tocchi. Ritorna return false, con l'eccezione su texte rangeinput.

$('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) Facoltativamente per l'app Internet integrata su Android (5.1, Samsung), inibisce i doppi tocchi su <div>, ma inibisce lo zoom su <div>:

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

(3) Per Chrome su Android 5.1, disabilita del tutto il doppio tocco, non inibisce lo zoom e non fa nulla riguardo al doppio tocco negli altri browser. L'inibizione del doppio tocco <meta name="viewport" ...>è irritante, perché <meta name="viewport" ...>sembra una buona pratica.

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


-4

Eccoci qui

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.