Elimine el retraso de 300 ms en los eventos de clic en mobile Safari


He leído que mobile Safari tiene un retraso de 300 ms en los eventos de clic desde el momento en que se hace clic en el enlace/botón hasta el momento en que se dispara el evento. La razón del retraso es esperar para ver si el usuario tiene la intención de hacer doble clic, pero desde una perspectiva de UX esperar 300ms a menudo es indeseable.

Una solución para eliminar este retraso de 300 ms es usar el manejo "tap" de jQuery Mobile. Desafortunadamente no estoy familiarizado con este marco y no quiero cargar un marco grande si todos Necesito una línea o dos de código aplicando touchend de la manera correcta.

Al igual que muchos sitios, mi sitio tiene muchos eventos de clic como este:

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

Y lo que me gustaría hacer es deshacerme del retraso de 300 ms en TODOS esos eventos de clic usando un solo fragmento de código como este:

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

¿Es una mala/buena idea?

Author: tim peterson, 2012-09-02

10 answers

Ahora algunos navegadores móviles eliminan 300 ms de retraso de clic si configura la ventana. Ya no necesitas usar soluciones alternativas.

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

Esto es actualmente Chrome compatible para Android, Firefox para Android y Safari para iOS

Sin embargo, en iOS Safari , el doble toque es un gesto de desplazamiento en páginas no accesibles. Por esa razón no pueden eliminar el retraso de 300 ms. Si no pueden eliminar el retraso en las páginas no accesibles, es poco probable para eliminarlo en páginas ampliables.

Windows Phones también conservan el retraso de 300 ms en las páginas descompensables, pero no tienen un gesto alternativo como iOS, por lo que es posible que eliminen este retraso como Chrome tiene. Puede eliminar el retraso en Windows Phone usando:

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

Fuente: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

ACTUALIZACIÓN 2015 Diciembre

Hasta ahora, WebKit y Safari en iOS tenían un retardo de 350 ms antes de toques individuales activar enlaces o botones para permitir a las personas hacer zoom en las páginas con un toque doble. Chrome cambió esto hace un par de meses ya mediante el uso de un algoritmo más inteligente para detectar que y ahora WebKit seguirá con un enfoque similar . El artículo ofrece algunas grandes ideas sobre cómo funcionan los navegadores con gestos táctiles y cómo los navegadores todavía pueden ser mucho más inteligentes de lo que son hoy en día.

ACTUALIZACIÓN 2016 Marzo

En Safari para iOS, los 350 ms esperan el tiempo para detectar un segundo toque se ha eliminado para crear una respuesta de "toque rápido". Esto está habilitado para páginas que declaran una vista con width=device-width o user-scalable=no. Los autores también pueden optar por el comportamiento de toque rápido en elementos específicos mediante el uso de la propiedad CSS touch-action, utilizando el valor de manipulación. Véase http://www.w3.org/TR/pointerevents/#the-touch-action-css-property .

 57
Author: NoNameProvided,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-21 23:02:00

Este plugin-FastClick desarrollado por Financial Times lo hace perfectamente para usted!

Asegúrese de agregar event.stopPropagation(); y / o event.preventDefault(); directamente después de la función de clic, de lo contrario podría ejecutarse dos veces como lo hizo para mí, es decir:

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

});
 42
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-10 09:41:08

Sé que esto es viejo, pero ¿no puedes probar para ver si "touch" es compatible con el navegador? Luego cree una variable que sea "touchend" o "click" y use esa variable como el evento que se vincula a su elemento?

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

De modo que code sample comprueba si el evento "touchend" está soportado en el navegador y si no, entonces usamos el evento "click".

(Editar: cambiado "touchend" a "ontouchend")

 15
Author: Michael Turnwall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-29 22:16:09

Me he encontrado con una alternativa muy popular llamada Hammer.js (Github page) que creo que es el mejor enfoque.

Martillo.js es una biblioteca táctil más completa (tiene muchos comandos de deslizamiento) que Fastclick.js (respuesta más votada).

Pero ten cuidado: desplazarse rápido en dispositivos móviles tiende a bloquear la interfaz de usuario cuando usas cualquiera de los dos Hammer.js o Fastclick.js. Este es un problema importante si su sitio tiene una fuente de noticias o una interfaz donde los usuarios se desplaza mucho (parecería como la mayoría de las aplicaciones web). Por esta razón, no estoy usando ninguno de estos plugins en este momento.

 11
Author: tim peterson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-04 15:17:23

De alguna manera, desactivar el zoom parece desactivar este pequeño retraso. Tiene sentido, ya que el doble toque ya no es necesario.

¿Cómo puedo "desactivar" el zoom en una página web móvil?

Pero tenga en cuenta el impacto en la usabilidad que esto tendrá. Puede ser útil para páginas web diseñadas como aplicaciones, pero no debe usarse para páginas 'estáticas' de propósito más general en mi humilde opinión. Lo uso para un proyecto de mascotas que necesita baja latencia.

 2
Author: ayke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:56

Desafortunadamente no hay una manera fácil de hacer esto. Así que solo usar touchstart o touchend te dejará con otros problemas como que alguien comience a desplazarse cuando haga clic en un botón, por ejemplo. Usamos zepto por un tiempo, e incluso con este marco realmente bueno hay algunos problemas que surgieron con el tiempo. Muchos de ellos soncerrados , pero parece que no es un campo de solución simple.

Tenemos esta solución para manejar globalmente los clics en los enlaces:

   $(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();
    });
 1
Author: Andreas Köberle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-02 20:27:53

Busqué una manera fácil sin jquery y sin biblioteca fastclick. Esto funciona para mí:

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);          
    }
}
 1
Author: Jarda Pavlíček,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-15 20:11:41

Solo para proporcionar información adicional.

En iOS 10, los <button> s de mi página no se podían activar continuamente. Siempre había un retraso.

Intenté fastclick / Hammer / tapjs / reemplazar click con touchstart, todo falló.

ACTUALIZACIÓN: la razón parece ser que el botón está demasiado cerca del borde! moverlo a cerca del centro y lag gone!

 0
Author: Dai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-07 10:29:36

Se supone que debes declarar explícitamente el modo pasivo :

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

    alert('fast touch');

}, { passive : true});
 0
Author: Bruno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-15 21:23:41

En jQuery puedes enlazar el evento "touchend", que activa el código inmediatamente después de tocar (es como un keydown en el teclado). Probado en las versiones actuales de Chrome y Firefox Tablet. No olvide "haga clic" también, para sus computadoras portátiles de pantalla táctil y dispositivos de escritorio.

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

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

	// everything else
});
 0
Author: Benjamin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-07 23:20:11