Safari iPad 1: как отключить масштабирование/центрирование при двойном касании, но сохраняйте масштабирование

Интересно, возможно ли предотвратить предотвращение двойного нажатия и масштабирования и двойного нажатия на центр в определенном элементе HTML в Safari iOS (iPad 1)?

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

Обнаружение двойных щелчков (например, в этом ответе - Safari iPad: предотвратите увеличение двойного касания) плохо пахнет..

Неверный ответ # 1: <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> - не подходит для моих целей, потому что он блокирует любое масштабирование.

Неверный ответ # 2:, возможно, для этого достаточно было бы .preventDefault() на событии click? - Не имеет никакого эффекта.

Ответ 1

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

Действительно, некоторые конкретные свойства/значения CSS могут изменять поведение глобального сайта (например, фиксированная ширина или fixed), но вы не можете быть в безопасности от изменений в ОС (см. fixed изменение обработки в iOS5), и эти изменения не обязательно предотвращают все поведение (пинч может быть выключен, но не двойным нажатием).

Таким образом, лучший способ отключить поведение по умолчанию только для двойного нажатия - использовать количество штрихов. iOS обеспечивает: если мы есть только один контакт, затем мы нажимаем. Два, это означает, что мы щипаем.

Следующий код настройки обеспечивает эту функциональность:

var elm = document.body; // or some selection of the element you want to disable

var catcher = function(evt) {
    if (evt.touches.length < 2)
        evt.preventDefault();
};

elm.addEventListener('touchstart', catcher, true);

Демо на jsFiddle.

Примечание: третий параметр (true) - addEventListener означает, что мы хотим захватить события, то есть поймать их всех, даже для наших детей-потомков.

Ответ 2

Я предотвращаю двойные нажатия следующим образом:

var doubleTouchStartTimestamp = 0;
$(document).bind("touchstart", function (event) {
    var now = +(new Date());
    if (doubleTouchStartTimestamp + 500 > now) {
        event.preventDefault();
    }
    doubleTouchStartTimestamp = now;
});

Элегантность заключается в том, что нет необходимости в тайм-аутах. Я обновляю только временную метку. Его сравнивают только на следующем касании. Работает для меня на iOS 6.

Двойное нажатие вниз по dom не влияет.

То же самое работает без jQuery:

var doubleTouchStartTimestamp = 0;
document.addEventListener("touchstart", function (event) {
    var now = +(new Date());
    if (doubleTouchStartTimestamp + 500 > now) {
        event.preventDefault();
    }
    doubleTouchStartTimestamp = now;
});

Ответ 3

Я написал плагин jQuery с той же целью - выборочно отключить масштабирование с двойным нажатием на заданные элементы страницы (в моем случае кнопки навигации для flip pages) Я хочу реагировать на каждое нажатие (включая двойное нажатие), как обычное событие клика, без iOS "touch magic", независимо от того, как быстро пользователь нажимает на него.

Чтобы использовать его, просто запустите что-то вроде $('.prev,.next').nodoubletapzoom(); на элементах, которые вам нужны. Принцип, который он использует, состоит в том, чтобы прослушивать последовательные события touchstart на node в пределах 500 мс и работать event.preventDefault() во втором, если другие касания не активны одновременно. Поскольку этот preventDefault потребляет оба касания, мы также синтезируем два события "пропущенных" щелчков для node, поэтому ваше предполагаемое действие касания происходит столько раз, сколько нужно пользователю.

Ответ 5

Какой браузер iOS/браузер Safari вы используете? Этот сайт определенно не позволяет вам дважды нажать. Я нашел несколько CSS, но не успел попробовать, так как я собираюсь выйти:

body {
  -webkit-text-size-adjust:none;
  margin:0px;
}

div{
  clear:both!important;
  display:block!important;
  width:100%!important;
  float:none!important;
  margin:0!important;
  padding:0!important;
}

Ответ 6

Вам понадобится реализовать функцию двойного нажатия и preventDefault на втором касании. Вот несколько проверенных кодов, в которых используются глобальные переменные, которые должны вас запустить:

<button id="test1">Double Tap Me!</button>
<div id="test2">EMPTY</div>

var elm1 = document.getElementById('test1');
var elm2 = document.getElementById('test2');
var timeout;
var lastTap = 0;
elm1.addEventListener('touchend', function(event) {
    var currentTime = new Date().getTime();
    var tapLength = currentTime - lastTap;
    clearTimeout(timeout);
    if (tapLength < 500 && tapLength > 0) {
        elm2.innerHTML = 'Double Tap';
        event.preventDefault();
    } else {
        elm2.innerHTML = 'Single Tap';
        timeout = setTimeout(function() {
            elm2.innerHTML = 'Single Tap (timeout)';
            clearTimeout(timeout);
        }, 500);
    }
    lastTap = currentTime;
});

И скрипка: http://jsfiddle.net/brettwp/J4djY/

Ответ 7

JQuery-подход для отключения Double Tap Zoom в MVC4 Чтобы отключить функцию двойного нажатия (двойной мыши) на iOS 1+, вам нужно поймать событие touchStart и создать переопределение для предотвращения масштабирования.

//Используя Single script.js и пользовательский интерфейс JQuery.Mobile-1.2.0, каждая страница в MVC получает JQuery через делегатов, поэтому вам не нужно полностью обновлять страницу, чтобы вы могли воспользоваться преимуществами предварительная выборка данных, которая загружает страницу в DOM, когда приложение загружается в первый раз

$(document).delegate( "# CashRegister", "pageinit", function() {

// To Disable 'Pinch to Zoom' Note: don't implement gester event handlers if you want to 
//keep pinch to zoom functionality NOTE: i use this as my pageinit is a delegate of a page
this.addEventListener("gesturestart", gestureStart, false);
this.addEventListener("gesturechange", gestureChange, false);
this.addEventListener("gestureend", gestureEnd, false);
//handle each event by disabling the defaults
function gestureStart(event) {
    event.preventDefault();
}

function gestureChange(event) {
    event.preventDefault();
}

function gestureEnd(event) {
    event.preventDefault();
}
//Recreate Double Tap and preventDefault on it
$(this).bind('touchstart', function preventZoom(e) {
// recreate the double tab functionality
        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');
    });

Ответ 8

Собственно,.preventDefault() определенно работает... с помощью jQuery:

var InputHandler = {    
    startEventType : isTouch ? "touchstart" : "mousedown"
}

$(selector).bind(InputHandler.startEventType, function(evnt) {
    evnt.preventDefault();
});

Ваша проблема с попыткой предотвратить использование .click() заключается в том, что браузер не бросает элемент "click". Safari только запускает щелчок, чтобы помочь имитировать клик... Но когда есть двойная вкладка, Safair не проходит через элемент "click". Ваш обработчик событий для .click() не срабатывает, поэтому .preventDefault() тоже не срабатывает.