En el desarrollo de aplicaciones móviles, los eventos de clic frecuentemente presantan un retraso de aproximadamente 300 milisegundos, lo que afecta la experiencia del usuario. Este cmoportamiento ocurre porque los navegadores esperan para detectar gestos de doble toque. Una solución eficaz es implementar un manejador de eventos táctiles optimizado que responda inmediatamente al toque inicial.
A continuación se presenta una biblioteca simplificada en JavaScript que elimina este retraso al sintetizar eventos de clic a partir de eventos táctiles. El código ha sido reestructurado para mejorar la legibilidad y modularidad:
(function() {
'use strict';
// Clase principal para gestionar clics táctiles rápidos
function TouchClickManager(elementoObjetivo, opciones) {
this.elemento = elementoObjetivo;
this.opciones = opciones || {};
this.umbralMovimiento = this.opciones.umbralMovimiento || 10;
this.maximoDuracionToque = this.opciones.maximoDuracionToque || 200;
this.toqueActivo = false;
this.coordenadasIniciales = { x: 0, y: 0 };
this.marcaTiempoInicio = 0;
this.configurarEventos();
}
TouchClickManager.prototype.configurarEventos = function() {
var contexto = this;
// Vincular métodos al contexto actual
this.manejarTouchStart = this.manejarTouchStart.bind(this);
this.manejarTouchEnd = this.manejarTouchEnd.bind(this);
this.manejarTouchCancel = this.manejarTouchCancel.bind(this);
// Registrar oyentes de eventos
this.elemento.addEventListener('touchstart', this.manejarTouchStart, false);
this.elemento.addEventListener('touchend', this.manejarTouchEnd, false);
this.elemento.addEventListener('touchcancel', this.manejarTouchCancel, false);
};
TouchClickManager.prototype.manejarTouchStart = function(evento) {
if (evento.targetTouches.length !== 1) return;
var toque = evento.targetTouches[0];
this.toqueActivo = true;
this.coordenadasIniciales = { x: toque.pageX, y: toque.pageY };
this.marcaTiempoInicio = Date.now();
};
TouchClickManager.prototype.manejarTouchEnd = function(evento) {
if (!this.toqueActivo) return;
var toqueFinal = evento.changedTouches[0];
var desplazamientoX = Math.abs(toqueFinal.pageX - this.coordenadasIniciales.x);
var desplazamientoY = Math.abs(toqueFinal.pageY - this.coordenadasIniciales.y);
var duracionToque = Date.now() - this.marcaTiempoInicio;
this.toqueActivo = false;
// Verificar si cumple criterios de clic rápido
if (duracionToque <= this.maximoDuracionToque &&
desplazamientoX <= this.umbralMovimiento &&
desplazamientoY <= this.umbralMovimiento) {
evento.preventDefault();
this.dispararClicSintetico(evento.target, toqueFinal);
}
};
TouchClickManager.prototype.manejarTouchCancel = function() {
this.toqueActivo = false;
};
TouchClickManager.prototype.dispararClicSintetico = function(elemento, toque) {
var eventoClic = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
screenX: toque.screenX,
screenY: toque.screenY,
clientX: toque.clientX,
clientY: toque.clientY
});
elemento.dispatchEvent(eventoClic);
};
// Método estático para inicialización rápida
TouchClickManager.inicializar = function(selector, opciones) {
var elementos = document.querySelectorAll(selector);
var instancias = [];
elementos.forEach(function(elemento) {
instancias.push(new TouchClickManager(elemento, opciones));
});
return instancias;
};
// Exportar al ámbito global
window.TouchClickManager = TouchClickManager;
})();
Para integrar esta solución en un proyecto que utiliza jQuery, basta con ejecutar la inicialización después de que el DOM esté listo:
$(function() {
TouchClickManager.inicializar('body', {
umbralMovimiento: 8,
maximoDuracionToque: 150
});
});
Este método permite que los eventos de clic se ejecuten con mayor rapidez en dispositivos táctiles, mejorando significativamente la interacción en aplicaciones web móviles.