Устраните задержку 300 мс на событиях click в мобильном Safari

Я читал, что мобильный Safari имеет 300-секундную задержку на событиях кликов с момента нажатия ссылки/кнопки до момента запуска события. Причиной задержки является ожидание, если пользователь намеревается дважды щелкнуть, но с точки зрения UX, ожидающей 300 мс, часто нежелательно.

Одно из решений, чтобы устранить эту задержку в 300 мсек, - это использование манипуляции jQuery Mobile "tap". К сожалению, я не знаком с этой инфраструктурой и не хочу загружать какую-либо большую структуру, если мне нужно только строка или два кода, применяющих touchend в правильном направлении.

Как и многие сайты, на моем сайте много кликов:

$("button.submitBtn").on('click', function (e) {   
  $.ajaxSubmit({... //ajax form submisssion
});

$("a.ajax").on('click', function (e) {   
  $.ajax({... //ajax page loading
});

$("button.modal").on('click', function (e) {   
      //show/hide modal dialog
});

и то, что я хотел бы сделать, - избавиться от задержки 300 мс на ВСЕ тех событиях щелчка, используя один фрагмент кода, например:

$("a, button").on('tap', function (e) {
 $(this).trigger('click');
 e.preventDefault();
});

Это плохая/хорошая идея?

Ответ 1

Теперь некоторые мобильные браузеры устраняют задержку клика 300 мс, если вы установили область просмотра. Вам больше не нужно использовать обходные пути.

<meta name="viewport" content="width=device-width, user-scalable=no">

В настоящее время это поддерживается Chrome для Android, Firefox для Android и Safari для iOS

Однако в iOS Safari двойное касание - это жест прокрутки на не масштабируемых страницах. По этой причине они не могут устранить задержку в 300 мс. Если они не могут убрать задержку на страницах с изменяемым масштабом, они вряд ли уберут ее на масштабируемых страницах.

Телефоны Windows также сохраняют задержку в 300 мс на не масштабируемых страницах, но у них нет альтернативного жеста, такого как iOS, поэтому они могут удалить эту задержку, как в Chrome. Вы можете удалить задержку на Windows Phone, используя:

html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}

Источник: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

ОБНОВЛЕНИЕ 2015 Декабрь

До сих пор WebKit и Safari на iOS имели задержку 350 мс, прежде чем одиночные касания активируют ссылки или кнопки, чтобы люди могли увеличивать страницы двойным касанием. Chrome изменил это пару месяцев назад, используя более умный алгоритм для обнаружения этого, и WebKit будет придерживаться аналогичного подхода. В статье дается отличное представление о том, как браузеры работают с сенсорными жестами и как браузеры могут стать намного умнее, чем сегодня.

ОБНОВЛЕНИЕ 2016 Март

В Safari для iOS время ожидания 350 мс для обнаружения второго касания было удалено, чтобы создать ответ "быстрого касания". Это включено для страниц, которые объявляют область просмотра с шириной = шириной устройства или масштабируемой пользователем = нет. Авторы также могут включить быстрое нажатие на определенные элементы с помощью touch-action: manipulation CSS touch-action: manipulation описанные здесь (прокрутите вниз до заголовка "Стиль поведения при быстром нажатии") и здесь.

Ответ 2

Этот плагин -FastClick, разработанный Financial Times, отлично подходит для вас!

Обязательно добавьте event.stopPropagation(); и/или event.preventDefault(); непосредственно после функции щелчка, иначе он может работать дважды, как и для меня, т.е.:

$("#buttonId").on('click',function(event){
    event.stopPropagation(); event.preventDefault();
   //do your magic

});

Ответ 3

Я знаю, что это старо, но разве вы не можете просто проверить, поддерживается ли "touch" в браузере? Затем создайте переменную "touchhend" или "click" и используйте эту переменную как событие, связанное с вашим элементом?

var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
    // do something
});

Итак, этот пример кода проверяет, поддерживается ли событие "touchhend" в браузере, а если нет, то мы используем событие "click".

(Edit: изменено "touchhend" на "ontouchend" )

Ответ 4

Я столкнулся с чрезвычайно популярной альтернативой под названием Hammer.js (Страница Github), который, по моему мнению, является наилучшим подходом.

Hammer.js - это более полнофункциональная сенсорная библиотека (имеет множество команд салфетки), чем Fastclick.js(самый высокий ответ).

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

Ответ 5

Как бы то ни было, отключение масштабирования отключает эту небольшую задержку. Имеет смысл, поскольку двойной щелчок больше не нужен.

Как я могу отключить " увеличить на мобильной веб-странице?

Но, пожалуйста, будьте внимательны к влиянию юзабилити, которое это будет иметь. Это может быть полезно для веб-страниц, разработанных как приложения, но не должно использоваться для более "статических" страниц общего назначения IMHO. Я использую его для проекта любителя, который нуждается в малой задержке.

Ответ 6

К сожалению, нет простого способа сделать это. Поэтому просто использование touchstart или touchend оставит вас с другими проблемами, например, когда кто-то начнет прокрутку, нажав, например, кнопку. Мы используем zepto какое-то время, и даже с этой действительно хорошей структурой возникают некоторые проблемы, которые возникли за это время. Многие из них закрыты, но, похоже, это не поле простого решения.

У нас есть это решение, чтобы глобально обрабатывать клики по ссылкам:

   $(document.body).
    on('tap', 'a',function (e) {
      var href = this.getAttribute('href');
      if (e.defaultPrevented || !href) { return; }
      e.preventDefault();
      location.href= href;
    }).
    on('click', 'a', function (e) {
      e.preventDefault();
    });

Ответ 7

Я искал простой способ без jquery и без библиотеки fastclick. Это работает для меня:

var keyboard = document.getElementById("keyboard");
var buttons = keyboard.children;
var isTouch = ("ontouchstart" in window);
for (var i=0;i<buttons.length;i++) {
    if ( isTouch ) {
        buttons[i].addEventListener('touchstart', clickHandler, false);         
    } else {
        buttons[i].addEventListener('click', clickHandler, false);          
    }
}

Ответ 8

Просто чтобы предоставить дополнительную информацию.

На iOS 10, <button> на моей странице не может быть запущено непрерывно. Всегда было отставание.

Я попробовал fastclick/Hammer/tapjs/заменить клик с помощью touchstart, все не удалось.

ОБНОВЛЕНИЕ: причина в том, что кнопка слишком близко к краю! переместите его ближе к центру и отстаньте!

Ответ 9

Вы должны явно объявить пассивный режим:

window.addEventListener('touchstart', (e) => {

    alert('fast touch');

}, { passive : true});

Ответ 10

В jQuery вы можете связать событие "touchhend", код запуска триггера, после нажатия (как клавиатура). Протестировано в текущих версиях планшета Chrome и Firefox. Не забудьте также "click" для ваших ноутбуков с сенсорным экраном и настольных устройств.

jQuery('.yourElements').bind('click touchend',function(event){

    event.stopPropagation();
    event.preventDefault();

	// everything else
});