Nonaktifkan ketuk dua kali opsi "zoom" di browser pada perangkat sentuh

112

Saya ingin menonaktifkan yang zoom double-tap fungsi pada elemen tertentu di browser (pada perangkat sentuh), tanpa menonaktifkan semua fungsi zoom .

Misalnya: Satu elemen dapat diketuk beberapa kali agar sesuatu terjadi. Ini berfungsi dengan baik di browser desktop (seperti yang diharapkan), tetapi di browser perangkat sentuh, ini akan memperbesar.

Wouter Konecny
sumber
Meskipun bukan untuk zoom, tetapi berikut adalah beberapa yang penting lainnya - `-webkit-touch-callout: none; -webkit-text-size-sesuaikan: tidak ada; -webkit-user-select: none;
Udayraj Deshmukh

Jawaban:

99

Catatan (per 2020-08-04): solusi ini tampaknya tidak berfungsi di iOS Safari v12 +. Saya akan memperbarui jawaban ini dan menghapus catatan ini setelah saya menemukan solusi jelas yang mencakup Safari iOS.

Solusi khusus CSS

Tambahkan touch-action: manipulationke elemen apa pun yang ingin Anda nonaktifkan zoom tap dua kali, seperti dengan disable-dbl-tap-zoomkelas berikut :

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

Dari touch-actiondokumen (penekanan dari saya):

manipulasi

Aktifkan gerakan panning dan cubit zoom, tetapi nonaktifkan gerakan non-standar tambahan seperti ketuk dua kali untuk memperbesar .

Nilai ini berfungsi di Android dan iOS.

Ross Allen
sumber
@SergoPasoevi, dapatkah Anda membuat contoh yang tidak berfungsi? Saya menggunakan solusi ini untuk iOS 12, dan ini berfungsi untuk saya.
Ross Allen
Saya melihat masalah yang sama dengan @SergoPasoevi, tidak berfungsi di iOS 12
Trevor Jex
Bekerja untuk saya di iOS 12!
KB2497
2
apa kerugian membungkus seluruh tubuh Anda dengan sentuhan-tindakan: manipulasi?
oygen
1
Tidak berfungsi pada iOS terbaru saat mengetuk gambar dua kali.
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>

Saya telah menggunakannya baru-baru ini dan berfungsi dengan baik di iPad. Belum diuji di Android atau perangkat lain (karena situs web hanya akan ditampilkan di iPad).

Kablam
sumber
16
Itu akan menonaktifkan SEMUA fungsi zoom, sayangnya itu bukan pertanyaan saya. Saya ingin menonaktifkan hanya elemen tertentu.
Wouter Konecny
Oi sial. Saya membacanya sebaliknya, gagal pada saya. Maaf!
Kablam
5
Bagaimana dengan solusi ini? Ini hanya untuk iOS, tapi mungkin dapat diubah? : Gist.github.com/2047491
Kablam
2
@WouterKonecny ​​Jika Anda menghapus pemeriksaan agen pengguna, seharusnya berfungsi pada perangkat apa pun yang mendukung acara mulai sentuh. Untuk mendeteksi perangkat tersebut, Anda dapat menggunakan sesuatu seperti isEventSupported
nxt
4
Apple sekarang secara resmi mengabaikan ini. github.com/w3c/html/issues/602
catamphetamine
38

Saya tahu ini mungkin sudah lama, tetapi saya menemukan solusi yang bekerja dengan sempurna untuk saya. Tidak perlu tag meta gila dan menghentikan pembesaran konten.

Saya tidak 100% yakin bagaimana lintas perangkat itu, tapi berhasil sesuai keinginan saya.

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

Ini hanya akan menonaktifkan fungsi penyadapan normal, dan kemudian memanggil peristiwa klik standar lagi. Ini mencegah perangkat seluler melakukan zoom, tetapi berfungsi seperti biasa.

EDIT: Ini sekarang telah teruji waktu dan berjalan di beberapa aplikasi langsung. Tampaknya 100% lintas-browser dan platform. Kode di atas seharusnya berfungsi sebagai solusi salin-tempel untuk kebanyakan kasus, kecuali Anda menginginkan perilaku khusus sebelum peristiwa klik.

Rockster 160
sumber
jawaban sederhana tapi bagus. tidak perlu mengubah tag meta atau dll.
benchpresser
2
ini menonaktifkan klik, saya rasa ini bukan solusi yang baik, maaf
Pixelomo
6
Anda tidak perlu JS untuk melakukan itu, Anda cukup mengatur atribut CSSpointer-events: none
Pixelomo
1
Terima kasih, ini berfungsi dengan sempurna untuk menangani tombol kenaikan / penurunan tanpa menonaktifkan zoom di seluruh halaman.
Ramón
1
Jika saya melihat ini dengan benar, ini mungkin gagal dalam situasi tertentu di mana Anda memerlukan peristiwa tepercaya (misalnya klik pada sth yang memicu layar penuh atau eksperimen lainnya, karena Anda memerlukan peristiwa tepercaya yang berarti DIMICATI OLEH PENGGUNA / OS)
Manuel Graf
29

Saya hanya ingin menjawab pertanyaan saya dengan benar karena beberapa orang tidak membaca komentar di bawah jawaban. Jadi begini:

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

Saya tidak menulis ini, saya hanya memodifikasinya. Saya menemukan versi khusus iOS di sini: https://gist.github.com/2047491 (terima kasih Kablam)

Wouter Konecny
sumber
1
Ini sepertinya tidak berhasil, setidaknya tidak pada SIII (w / Android 4.0.4). Saya mencoba mengikat ke dokumen, badan, jendela, *, tanpa dadu.
Maks
Mencoba saya juga, berfungsi di safari / ipad, android chrome tetapi tidak dengan browser default android
Strae
2
jquery bukanlah javascript alangkah baiknya memiliki contoh bagaimana melakukan ini tanpa perpustakaan
Martijn Scheffer
Mencari versi non-jquery :-(
Timo
sekali lagi, jQuery bukanlah javascript, dan tidak boleh didorong, karena tidak berfungsi baik dengan situs yang didasarkan pada ide yang lebih modern seperti sudut. baca pertanyaannya
Martijn Scheffer
15

CSS untuk menonaktifkan zoom ketuk dua kali secara global (pada elemen apa pun):

  * {
      touch-action: manipulation;
  }

manipulasi

Aktifkan gerakan panning dan cubit zoom, tetapi nonaktifkan gerakan non-standar tambahan seperti ketuk dua kali untuk memperbesar.

Terima kasih Ross, jawaban saya meluas: https://stackoverflow.com/a/53236027/9986657

Jan
sumber
1
Ini harus ditandai jawabannya. Saya mencoba meletakkannya hanya di html dan body tetapi tidak berhasil di iOS 13.2. Ini bekerja.
R OMS
Ini tidak berfungsi di iOS 13 dengan sendirinya, tetapi sehubungan dengan kode ini, ia mengetuk untuk memperbesar aplikasi React sepenuhnya. document.getElementById('root').addEventListener('click', () => {})
Sergei
apel menonaktifkan tap untuk memperbesar di ios13, bagaimana Anda bisa mengatakan bahwa itu tidak berfungsi di iOS13?
oygen
15

Jika Anda membutuhkan versi yang berfungsi tanpa jQuery , saya memodifikasi jawaban Wouter Konecny (yang juga dibuat dengan memodifikasi inti ini oleh Johan Sundström ) untuk menggunakan vanilla 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();
}

Kemudian tambahkan penangan kejadian touchstartyang memanggil fungsi ini:

myButton.addEventListener('touchstart', preventZoom); 
Evrim Persembe
sumber
3
cemerlang. hanya ingin menyebutkan bahwa saya perlu menambahkan addEventListener untuk memanggilnya. myButton.addEventListener('touchstart', preventZoom);
martin jakubik
11

Anda harus mengatur properti css touch-actionuntuk noneseperti yang dijelaskan dalam jawaban lain ini https://stackoverflow.com/a/42288386/1128216

.disable-doubletap-to-zoom {
    touch-action: none;
}
Jonathan Morales Vélez
sumber
1
Ini berfungsi ... tetapi bagaimana jika saya ingin menonaktifkan zoom, tetapi meninggalkan acara sentuh lainnya? Saya memiliki meja besar dan ini juga menonaktifkan pengguliran.
FrenkyB
2
Jika Anda hanya ingin menghilangkan zoom tap dua kali, Anda harus menyetel nilainya ke 'touch-action: manipulate;' Ini masih memungkinkan panning dan pinch-zooming. Catatan Penting: Ini juga membantu menghilangkan browser penundaan klik yang diperkenalkan untuk menerapkan zoom ketuk dua kali. lihat developer.mozilla.org/en-US/docs/Web/CSS/touch-action
cschuff
Pada tag HTML apa kelas ini harus ditambahkan?
Razvan Zamfir
Saya pikir Anda bisa menambahkannya ke elemen apa pun yang tidak ingin Anda gunakan untuk memperbesar. Misalnya, dalam kasus saya, saya tidak ingin pengguna memperbesar bagian mana pun dari halaman saya, jadi saya menambahkannya ke tag body.
Jonathan Morales Vélez
2
* {
    -ms-touch-action: manipulation;
    touch-action: manipulation;
}

Nonaktifkan ketuk dua kali untuk memperbesar layar sentuh. Penjelajah Internet disertakan.

Erçin Dedeoğlu
sumber
1

Sederhana mencegah perilaku default click, dblclickatau touchendperistiwa akan menonaktifkan fungsionalitas zoom.

Jika Anda sudah memiliki panggilan balik di salah satu acara ini, cukup panggil a event.preventDefault().

William Grasel
sumber
1
Ini berhasil untuk saya. Saya mendefinisikan event touchstart saya sendiri pada sebuah tombol, dan saya ingin menonaktifkan fungsi zoom.
Rick Giuly
1

Jika ada orang seperti saya yang mengalami masalah ini menggunakan Vue.js , cukup menambahkan .prevent sudah cukup :@click.prevent="someAction"

Sølve Tornøe
sumber
0

Ini akan mencegah zoom tap dua kali pada elemen di 'body' ini dapat diubah ke pemilih lainnya

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

});

Namun ini juga mencegah peristiwa klik saya terpicu saat diklik beberapa kali, jadi saya harus mengikat peristiwa lain untuk memicu peristiwa tersebut dengan beberapa klik

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

Pada touchstart saya menambahkan kode untuk mencegah zoom dan memicu klik.

$('.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
sumber
-1

Saya berasumsi bahwa saya memiliki <div>area wadah input dengan teks, slider dan tombol di dalamnya, dan ingin mencegah ketukan ganda yang tidak disengaja di dalamnya <div>. Hal berikut tidak menghalangi zoom pada area input, dan ini tidak terkait dengan ketuk dua kali dan zoom di luar <div>area saya . Ada variasi tergantung pada aplikasi browser.

Saya baru mencobanya.

(1) Untuk Safari di iOS, dan Chrome di Android, dan merupakan metode yang disukai. Berfungsi kecuali untuk aplikasi Internet di Samsung, yang menonaktifkan ketukan dua kali tidak secara penuh <div>, tetapi setidaknya pada elemen yang menangani ketukan. Ia kembali return false, dengan pengecualian textdan rangemasukan.

$('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) Secara opsional untuk aplikasi Internet internal di Android (5.1, Samsung), menghambat ketukan dua kali pada <div>, tetapi menghambat zoom pada <div>:

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

(3) Untuk Chrome di Android 5.1, menonaktifkan ketuk dua kali sama sekali, tidak menghalangi pembesaran, dan tidak melakukan apa pun terkait ketuk dua kali di browser lain. Penghambatan ketuk dua kali <meta name="viewport" ...>menjengkelkan, karena <meta name="viewport" ...>tampaknya praktik yang baik.

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

Kita mulai

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

tidak yakin
sumber