ปิดใช้งานตัวเลือก "ซูม" แตะสองครั้งในเบราว์เซอร์บนอุปกรณ์ระบบสัมผัส


112

ฉันต้องการปิดการใช้งานฟังก์ชันการซูมด้วยการแตะสองครั้งบนองค์ประกอบที่ระบุในเบราว์เซอร์ (บนอุปกรณ์ระบบสัมผัส) โดยไม่ต้องปิดฟังก์ชันการซูมทั้งหมด

ตัวอย่างเช่น: องค์ประกอบหนึ่งสามารถแตะได้หลายครั้งเพื่อให้บางสิ่งเกิดขึ้น ใช้งานได้ดีบนเบราว์เซอร์เดสก์ท็อป (ตามที่คาดไว้) แต่ในเบราว์เซอร์ของอุปกรณ์ระบบสัมผัสจะซูมเข้า


แม้ว่าจะไม่ใช่สำหรับการซูม แต่นี่คือสิ่งที่จำเป็นอื่น ๆ - `-webkit-touch-callout: none; -webkit-text-size-adjustment: ไม่มี; -webkit-user-select: ไม่มี;
Udayraj Deshmukh

คำตอบ:


99

หมายเหตุ (ณ วันที่ 2020-08-04): ดูเหมือนว่าโซลูชันนี้จะไม่ทำงานใน iOS Safari v12 + ฉันจะอัปเดตคำตอบนี้และลบบันทึกนี้เมื่อพบวิธีแก้ปัญหาที่ชัดเจนซึ่งครอบคลุม iOS Safari

โซลูชัน CSS เท่านั้น

เพิ่มtouch-action: manipulationองค์ประกอบใด ๆ ที่คุณต้องการปิดใช้งานการซูมด้วยการแตะสองครั้งเช่นเดียวกับdisable-dbl-tap-zoomคลาสต่อไปนี้:

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

จากtouch-actionเอกสาร (เน้นของฉัน):

การจัดการ

เปิดใช้งานการแพนและซูมหยิกท่าทาง แต่ปิดการใช้ท่าทางที่ไม่ได้มาตรฐานเพิ่มเติมเช่นแตะสองครั้งเพื่อซูม

ค่านี้ใช้ได้กับ Android และบน iOS


@SergoPasoevi คุณสร้างตัวอย่างที่ใช้ไม่ได้หรือไม่? ฉันใช้โซลูชันนี้สำหรับ iOS 12 และใช้งานได้สำหรับฉัน
Ross Allen

ฉันเห็นปัญหาเดียวกันกับ @SergoPasoevi ไม่ทำงานบน iOS 12
Trevor Jex

ทำงานให้ฉันบน iOS 12!
KB2497

2
อะไรคือข้อเสียของการห่อร่างกายของคุณด้วยการสัมผัส: การจัดการ?
oygen

1
ไม่ทำงานบน iOS ล่าสุดเมื่อแตะสองครั้งที่รูปภาพ
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>

ฉันเพิ่งใช้มันเมื่อไม่นานมานี้และใช้งานได้ดีบน iPad ยังไม่ได้ทดสอบบน Android หรืออุปกรณ์อื่น ๆ (เนื่องจากเว็บไซต์จะแสดงบน iPad เท่านั้น)


16
ซึ่งจะปิดการใช้งานฟังก์ชันการซูมทั้งหมด แต่นั่นไม่ใช่คำถามของฉัน ฉันต้องการปิดใช้งานเฉพาะองค์ประกอบที่ระบุ
Wouter Konecny

ออยอึ ฉันอ่านในทางกลับกันความล้มเหลวของฉัน ขออภัย!
Kablam

5
วิธีแก้ปัญหานี้เป็นอย่างไร? เป็น iOS เท่านั้น แต่อาจปรับแต่งได้? : gist.github.com/2047491
Kablam

2
@WouterKonecny ​​หากคุณลบ useragent ตรวจสอบว่าควรใช้งานได้กับอุปกรณ์ใด ๆ ที่รองรับเหตุการณ์ touchstart ในการตรวจจับอุปกรณ์เหล่านั้นคุณสามารถใช้สิ่งต่างๆเช่นisEventSupported
nxt

4
ตอนนี้ Apple เพิกเฉยต่อสิ่งนี้อย่างเป็นทางการ github.com/w3c/html/issues/602
catamphetamine

38

ฉันรู้ว่านี่อาจจะเก่า แต่ฉันพบวิธีแก้ปัญหาที่เหมาะกับฉัน ไม่จำเป็นต้องมีเมตาแท็กที่บ้าคลั่งและหยุดการซูมเนื้อหา

ฉันไม่แน่ใจ 100% ว่ามันข้ามอุปกรณ์ขนาดไหนแต่มันได้ผลตามที่ฉันต้องการ

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

สิ่งนี้จะปิดใช้งานฟังก์ชันการแตะปกติจากนั้นเรียกเหตุการณ์คลิกมาตรฐานอีกครั้ง ซึ่งจะป้องกันไม่ให้อุปกรณ์เคลื่อนที่ซูม แต่จะทำงานได้ตามปกติ

แก้ไข: ขณะนี้ได้รับการทดสอบตามเวลาและทำงานในแอปถ่ายทอดสดสองสามแอป ดูเหมือนว่าจะเป็นข้ามเบราว์เซอร์และแพลตฟอร์ม 100% โค้ดด้านบนควรใช้เป็นโซลูชันการคัดลอกและวางในกรณีส่วนใหญ่เว้นแต่คุณจะต้องการลักษณะการทำงานที่กำหนดเองก่อนเหตุการณ์คลิก


คำตอบที่เรียบง่าย แต่ยอดเยี่ยม ไม่จำเป็นต้องแก้ไขเมตาแท็กหรืออื่น ๆ
benchpresser

2
สิ่งนี้ปิดใช้งานการคลิกฉันไม่คิดว่ามันเป็นทางออกที่ดีขออภัย
Pixelomo

6
คุณไม่จำเป็นต้องใช้ JS ในการทำเพียงแค่ตั้งค่าแอตทริบิวต์ CSSpointer-events: none
Pixelomo

1
ขอบคุณสิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับการจัดการปุ่มเพิ่ม / ลดโดยไม่ต้องปิดการซูมบนทั้งหน้า
Ramón

1
หากฉันเห็นสิ่งนี้ถูกต้องสิ่งนี้อาจล้มเหลวในบางสถานการณ์ที่คุณต้องการเหตุการณ์ที่เชื่อถือได้ (เช่น clickin on sth ซึ่งเรียกใช้แบบเต็มหน้าจอหรือการทดลองอื่น ๆ เนื่องจากเหตุการณ์ที่เชื่อถือได้ซึ่งหมายความว่าถูกทริกเกอร์โดยผู้ใช้ / ระบบปฏิบัติการ)
Manuel Graf

29

ฉันแค่อยากจะตอบคำถามของฉันอย่างถูกต้องเนื่องจากบางคนไม่ได้อ่านความคิดเห็นด้านล่างคำตอบ นี่คือ:

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

ฉันไม่ได้เขียนสิ่งนี้ฉันเพิ่งแก้ไขมัน ฉันพบเวอร์ชัน iOS เท่านั้นที่นี่: https://gist.github.com/2047491 (ขอบคุณ Kablam)


1
ดูเหมือนจะไม่ได้ผลอย่างน้อยก็ไม่ได้อยู่ใน SIII (w / Android 4.0.4) ฉันพยายามผูกกับเอกสารเนื้อหาหน้าต่าง * ไม่มีลูกเต๋า
สูงสุด

ลองฉันด้วยใช้งานได้กับซาฟารี / iPad, Android Chrome แต่ไม่ใช่กับเบราว์เซอร์เริ่มต้นของ Android
Strae

2
jquery ไม่ใช่ javascript จะเป็นการดีที่จะมีตัวอย่างวิธีการทำสิ่งนี้โดยไม่มีห้องสมุด
Martijn Scheffer

กำลังมองหาเวอร์ชันที่ไม่ใช่ jquery :-(
Timo

อีกครั้ง jQuery ไม่ใช่ javascript และไม่ควรได้รับการสนับสนุนเนื่องจากไม่สามารถทำงานได้ดีกับไซต์ที่ใช้แนวคิดที่ทันสมัยกว่าเช่นเชิงมุม อ่านคำถาม
Martijn Scheffer

16

CSS เพื่อปิดใช้งานการซูมสองครั้งทั่วโลก (ในองค์ประกอบใด ๆ ):

  * {
      touch-action: manipulation;
  }

การจัดการ

เปิดใช้งานท่าทางการซูมและการซูม แต่ปิดใช้ท่าทางสัมผัสที่ไม่ได้มาตรฐานเพิ่มเติมเช่นแตะสองครั้งเพื่อซูม

ขอบคุณรอสคำตอบของฉันขยายความ: https://stackoverflow.com/a/53236027/9986657


1
สิ่งนี้ควรถูกทำเครื่องหมายคำตอบ ฉันลองใส่เฉพาะใน html และ body แต่ใช้ไม่ได้ใน iOS 13.2 นี้ได้ผล
R OMS

สิ่งนี้ใช้ไม่ได้บน iOS 13 ด้วยตัวเอง แต่ในการเชื่อมต่อกับรหัสนี้จะทำให้แตะเพื่อซูมสำหรับแอป React อย่างสมบูรณ์ document.getElementById('root').addEventListener('click', () => {})
Sergei

apple ปิดการใช้งานแตะเพื่อซูมบน ios13 คุณจะบอกว่ามันไม่ทำงานบน iOS13 ได้อย่างไร?
oygen

15

หากคุณต้องการเวอร์ชันที่ใช้งานได้โดยไม่มี jQueryฉันแก้ไขคำตอบของ Wouter Konecny (ซึ่งสร้างขึ้นโดยการแก้ไขส่วนสำคัญนี้โดยJohan Sundström ) เพื่อใช้วานิลลา 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();
}

จากนั้นเพิ่มตัวจัดการเหตุการณ์touchstartที่เรียกใช้ฟังก์ชันนี้:

myButton.addEventListener('touchstart', preventZoom); 

3
ยอดเยี่ยม แค่อยากจะบอกว่าฉันต้องเพิ่ม addEventListener เพื่อที่จะเรียกสิ่งนี้ myButton.addEventListener('touchstart', preventZoom);
martin jakubik

11

คุณควรตั้งค่าคุณสมบัติของ CSS touch-actionไปnoneตามที่อธิบายไว้ในคำตอบอื่น ๆhttps://stackoverflow.com/a/42288386/1128216

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

1
ใช้งานได้ ... แต่ถ้าฉันต้องการปิดการซูม แต่ออกจากเหตุการณ์สัมผัสอื่น ๆ ล่ะ? ฉันมีโต๊ะขนาดใหญ่และปิดใช้งานการเลื่อนด้วย
FrenkyB

2
หากคุณต้องการกำจัดการซูมด้วยการแตะสองครั้งเท่านั้นคุณควรตั้งค่าเป็น "touch-action: manipulate;" ซึ่งจะยังคงอนุญาตให้แพนและซูมนิ้วได้ หมายเหตุสำคัญ: วิธีนี้ยังช่วยกำจัดเบราว์เซอร์หน่วงเวลาคลิกที่นำมาใช้เพื่อใช้การซูมด้วยการแตะสองครั้ง ดูdeveloper.mozilla.org/en-US/docs/Web/CSS/touch-action
cschuff

คลาสนี้ควรเพิ่มแท็ก HTML ใด
Razvan Zamfir

ฉันคิดว่าคุณสามารถเพิ่มลงในองค์ประกอบใดก็ได้ที่คุณไม่ต้องการให้ใช้ขยาย ตัวอย่างเช่นในกรณีของฉันฉันไม่ต้องการให้ผู้ใช้ซูมเข้าไปในส่วนใด ๆ ของหน้าฉันจึงเพิ่มลงในแท็กเนื้อหา
Jonathan Morales Vélez

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

ปิดใช้งานการแตะสองครั้งเพื่อซูมบนหน้าจอสัมผัส รวม Internet Explorer


1

อย่างง่ายป้องกันพฤติกรรมเริ่มต้นของclickมิdblclickฉะนั้นtouchendเหตุการณ์จะปิดฟังก์ชันการซูม

หากคุณมีการติดต่อกลับเกี่ยวกับเหตุการณ์ใดเหตุการณ์หนึ่งevent.preventDefault()แล้วให้โทรหาไฟล์.


1
สิ่งนี้ได้ผลสำหรับฉัน ฉันกำลังกำหนดเหตุการณ์ทัชสตาร์ตของตัวเองบนปุ่มและต้องการปิดใช้งานฟังก์ชันซูม
Rick Giuly


0

วิธีนี้จะป้องกันการซูมสองครั้งที่องค์ประกอบใน "ร่างกาย" ซึ่งสามารถเปลี่ยนเป็นตัวเลือกอื่นได้

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

});

แต่สิ่งนี้ยังป้องกันไม่ให้เหตุการณ์การคลิกของฉันทริกเกอร์เมื่อคลิกหลายครั้งดังนั้นฉันจึงต้องผูกเหตุการณ์อื่นเพื่อทริกเกอร์เหตุการณ์ด้วยการคลิกหลายครั้ง

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

ในการเริ่มต้นสัมผัสฉันได้เพิ่มรหัสเพื่อป้องกันการซูมและทำให้เกิดการคลิก

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

ฉันคิดว่าฉันจะมีพื้นที่ภาชนะการป้อนข้อมูลที่มีข้อความเลื่อนและปุ่มในนั้นและต้องการที่จะยับยั้งอุบัติเหตุดับเบิลก๊อกในการที่<div> <div>สิ่งต่อไปนี้ไม่ได้ขัดขวางการซูมบนพื้นที่ป้อนข้อมูลและไม่เกี่ยวข้องกับการแตะสองครั้งและการซูมนอก<div>พื้นที่ของฉัน มีรูปแบบต่างๆขึ้นอยู่กับแอปเบราว์เซอร์

ผมเพิ่งลองทำ

(1) สำหรับ Safari บน iOS และ Chrome บน Android และเป็นวิธีที่แนะนำ ใช้งานได้ยกเว้นแอพอินเทอร์เน็ตบน Samsung ซึ่งจะปิดการใช้งานการแตะสองครั้งไม่ได้อยู่บนเต็ม<div>แต่อย่างน้อยก็ในองค์ประกอบที่จัดการกับการแตะ จะส่งคืนreturn falseโดยมีข้อยกเว้นtextและrangeอินพุต

$('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) เป็นทางเลือกสำหรับแอปอินเทอร์เน็ตในตัวบน Android (5.1, Samsung) ยับยั้งการแตะสองครั้งบน<div>แต่จะยับยั้งการซูมบน<div>:

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

(3) สำหรับ Chrome บน Android 5.1 ให้ปิดใช้งานการแตะสองครั้งเลยไม่ขัดขวางการซูมและไม่ทำอะไรเลยเกี่ยวกับการแตะสองครั้งในเบราว์เซอร์อื่น ๆ การยับยั้งการแตะสองครั้ง<meta name="viewport" ...>เป็นสิ่งที่น่ารำคาญเพราะ<meta name="viewport" ...>ดูเหมือนจะเป็นแนวทางปฏิบัติที่ดี

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

-2

การใช้ CSS touch-events: ไม่มีการนำเหตุการณ์การสัมผัสทั้งหมดออกไปโดยสิ้นเชิง ออกจากที่นี่เผื่อว่ามีคนมีปัญหานี้ด้วยใช้เวลา 2 ชั่วโมงในการหาวิธีแก้ปัญหานี้และมันเป็น css เพียงบรรทัดเดียว https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.