Отключить опцию двойного касания «масштабирования» в браузере на сенсорных устройствах

113

Я хочу , чтобы отключить в два раз водопроводного масштабирования функциональности на указанных элементах в браузере (на сенсорных устройствах), не отключая все функциональные возможности масштабирования .

Например: один элемент можно коснуться несколько раз, чтобы что-то произошло. Это отлично работает в браузерах настольных компьютеров (как и ожидалось), но в браузерах сенсорных устройств масштабирование будет увеличиваться.

Воутер Конечны
источник
Хотя не для масштабирования, но вот еще несколько важных: `-webkit-touch-callout: none; -webkit-text-size-adjust: нет; -webkit-user-select: нет;
Udayraj Deshmukh

Ответы:

100

Примечание (по состоянию на 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, и оно у меня работает.
Росс Аллен
Я вижу ту же проблему, что и @SergoPasoevi, не работает на iOS 12
Тревор Джекс
У меня работало на iOS 12!
KB2497
2
каковы минусы обертывания всего тела сенсорным действием: манипуляция?
oygen
1
Не работает на последней версии iOS при двойном нажатии на изображение.
Адам Сильвер,
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
Это отключит ВСЕ функции масштабирования, к сожалению, это был не мой вопрос. Я хочу отключить только указанные элементы.
Воутер Конечны
Ой, дерьмо. Я читаю наоборот, неудача на мне. Сожалею!
Kablam
5
Как насчет этого решения? Это только iOS, но, возможно, его можно настроить? : Gist.github.com/2047491
Kablam
2
@WouterKonecny ​​Если вы удалите проверку агента пользователя, он должен работать на любом устройстве, поддерживающем событие touchstart. Для того, чтобы обнаружить те устройства , которые вы можете использовать что - то вроде isEventSupported
NXT
4
Apple теперь официально игнорирует это. github.com/w3c/html/issues/602
катамфетамин
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% кроссбраузерность и платформа. Приведенный выше код должен работать как решение для копирования и вставки в большинстве случаев, если вы не хотите настраивать поведение перед событием щелчка.

Рокстер160
источник
простой, но отличный ответ. нет необходимости изменять метатеги и т. д.
Benchpresser
2
это отключает клики, я не думаю, что это хорошее решение, извините
Pixelomo
6
для этого вам не нужен JS, вы можете просто установить атрибут CSSpointer-events: none
Pixelomo 01
1
Спасибо, это отлично сработало для обработки кнопок увеличения / уменьшения без отключения масштабирования всей страницы.
Ramón
1
Если я вижу это правильно, это может привести к сбою в определенных ситуациях, когда вам нужны доверенные события (например, щелчок по sth, который запускает полноэкранный режим или другие эксперименты, как yneed доверенные события, что означает TRIGGERED BY USER / OS)
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 (с Android 4.0.4). Я пробовал привязать к документу, телу, окну, *, без кубика.
Макс
Пробовал и меня, работает на Safari / iPad, Android Chrome, но не с браузером по умолчанию для Android
Strae
2
jquery - это не javascript, было бы неплохо получить пример того, как это сделать без библиотеки,
Мартин Шеффер,
Ищу версию без jquery :-(
Timo
Опять же, jQuery не является javascript, и его не следует поощрять, поскольку он не работает с сайтами, основанными на более современных идеях, таких как angular. прочитайте вопрос
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', () => {})
Сергей
яблоко отключил тап для увеличения на ios13, как можно сказать, что он не работает на iOS13?
oygen
15

Если вам нужна версия , которая работает без JQuery , я изменил ответ Wouter Конечны (который также был создан путем модификации этого суть по Johan Сундстрём ) использовать ванильный 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);
Мартин Якубик
11

Вы должны установить свойство CSS , touch-actionчтобы , noneкак описано в этом другом ответе https://stackoverflow.com/a/42288386/1128216

.disable-doubletap-to-zoom {
    touch-action: none;
}
Джонатан Моралес Велес
источник
1
Это работает ... но что, если я хочу отключить масштабирование, но оставить другие события касания? У меня большая таблица, и это тоже отключает прокрутку.
FrenkyB
2
Если вы хотите избавиться только от масштабирования двойным касанием, вам следует установить значение 'touch-action: manage;' Это по-прежнему позволит панорамировать и масштабировать пальцем. Важное примечание: это также помогает избавиться от браузеров с задержкой щелчка, представленных для реализации масштабирования двойным касанием. см. developer.mozilla.org/en-US/docs/Web/CSS/touch-action
cschuff
В какой HTML-тег следует добавить этот класс?
Разван Замфир
Я думаю, вы можете просто добавить его к любому элементу, который вы не хотите использовать для увеличения. Например, в моем случае я не хотел, чтобы пользователь увеличивал какую-либо часть моей страницы, поэтому я добавил это в тег body.
Джонатан Моралес Велес,
2
* {
    -ms-touch-action: manipulation;
    touch-action: manipulation;
}

Отключите двойное касание для увеличения на сенсорных экранах. Internet Explorer включен.

Эрчин Дедеоглу
источник
1

Простое поведение по умолчанию click, dblclickили touchendсобытия отключить функции масштабирования.

Если у вас уже есть обратный вызов для одного из этих событий, просто вызовите event.preventDefault().

Уильям Грейсель
источник
1
Это сработало для меня. Я определял собственное событие touchstart для кнопки и хотел отключить функцию масштабирования.
Рик Джули
1

Если кто-то вроде меня сталкивается с этой проблемой при использовании Vue.js , простое добавление .prevent поможет:@click.prevent="someAction"

Сёльве Торнё
источник
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: нет Полностью удаляет все сенсорные события. Просто оставив это здесь на случай, если у кого-то также возникнут эти проблемы, мне потребовалось 2 часа, чтобы найти это решение, и это всего лишь одна строка css. https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

Асгейр Фримансон
источник
-4

Вот так

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

Точно сказать не могу
источник