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


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

решение чтобы устранить эту задержку 300 мс, необходимо использовать jQuery Mobile "tap" handling. К сожалению, я не знаком с этой структурой и не хочу загружать некоторые большой фреймворк, если все, что мне нужно, это строка или два кода применения 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();
});

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

10 80

10 ответов:

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

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

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

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

Windows Phones также сохраняйте задержку 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 мс для обнаружения второго нажатия было удалено, чтобы создать ответ "быстрого нажатия". Это включено для страниц, которые объявляют видовой экран с шириной=ширина устройства или масштабируемый пользователем=нет. Авторы также могут выбрать режим быстрого нажатия на определенные элементы с помощью CSS свойство touch-action, использующее значение манипуляции. Смотрите http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.

этот плагин-FastClick разработан Financial Times это прекрасно для вас!

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

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

});

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

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

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

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

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

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

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

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

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

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

к сожалению, нет простого способа сделать это. Так что просто с помощью 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();
    });

Я искал простой способ без 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);          
    }
}

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

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

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

обновление: причина, кажется, в том, что кнопка слишком близко к краю! переместить его ближе к центру и лагов нет!

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

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

    alert('fast touch');

}, { passive : true});

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

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

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

	// everything else
});