Un desarrollador que crea detección de pellizco con dos dedos usando escuchas TouchEvent enviará código que funciona perfectamente en un teléfono Android y que silenciosamente no hace nada en una laptop con Windows. La razón es arquitectónica, no un error del navegador: un trackpad de escritorio no dispara TouchEvent en absoluto. Saber qué eventos produce realmente cada dispositivo de entrada — y por qué — es el requisito previo para escribir código de gestos que funcione en todas las categorías de dispositivos.
Qué son PointerEvent y TouchEvent
TouchEvent es la API más antigua de las dos. Introducida para manejar la entrada táctil con los dedos en pantallas móviles, entrega una lista de contactos activos (touches, targetTouches, changedTouches) a través de eventos llamados touchstart, touchmove, touchend y touchcancel. Cada entrada en esas listas es un objeto Touch con sus propias coordenadas e identificador. La API fue diseñada específicamente para pantallas táctiles, y ese origen se nota: no tiene concepto de mouse, lápiz o trackpad.
PointerEvent es el reemplazo unificado del W3C, lanzado primero en Internet Explorer 11 y ahora parte de todos los navegadores principales. Maneja mouse, lápiz y tacto mediante una sola familia de eventos — pointerdown, pointermove, pointerup, pointercancel — y expone una propiedad pointerType en cada evento que indica la fuente: "mouse", "pen" o "touch". La documentación de MDN sobre Pointer Events describe el modelo completo; la especificación W3C se mantiene en w3c.github.io/pointerevents.
Qué dispara realmente un trackpad de escritorio
Esta es la parte que sorprende a la mayoría de desarrolladores: un trackpad de laptop en un sistema operativo de escritorio no dispara TouchEvent, ni produce PointerEvent con pointerType: "touch". Dispara:
- PointerEvent con
pointerType: "mouse"— el movimiento y clics de contacto único llegan como eventos ordinarios de puntero-mouse. El navegador no puede saber solo por el evento si el dispositivo físico fue un mouse o un trackpad. - WheelEvent — el desplazamiento con dos dedos en un trackpad produce un evento
wheel, exactamente como lo haría la rueda de desplazamiento de un mouse. Las propiedadesdeltaXydeltaYreportan las cantidades de desplazamiento. - WheelEvent con
ctrlKey: true— el sistema operativo convierte el gesto de pellizco para zoom en un eventowheelcon la banderactrlKeyactivada. Esta es la señal estándar entre navegadores para zoom con trackpad. Las páginas web que interceptanctrl+wheelpara implementar zoom personalizado están aprovechando exactamente esta convención.
Las pantallas táctiles, en cambio, disparan PointerEvent con pointerType: "touch" — y en navegadores que aún mantienen la API heredada, también TouchEvent. Dos dedos en una pantalla táctil producen dos eventos pointerdown simultáneos, cada uno con un pointerId distinto, que el código web puede usar directamente para calcular la escala del pellizco comparando la distancia entre punteros.
Por qué la distinción importa para el código de gestos
Las consecuencias prácticas se dividen en tres patrones:
- Pellizco con dos dedos en pantalla táctil — detectable rastreando dos eventos
pointerdownconcurrentes (o dos entradas enTouchEvent.touches) y calculando la distancia entre ellos a través de eventospointermove. Este patrón funciona en móvil pero no produce nada útil en un trackpad de escritorio, porque el trackpad nunca envía dos contactos simultáneos al navegador. - Pellizco para zoom en trackpad — detectable solo mediante evento
wheelconctrlKey === true. No se necesita ni es posible hacer cálculos con dos punteros. El sistema operativo ya convirtió el gesto de dos dedos en un delta escalar de zoom antes de que el navegador vea algo. - Desplazamiento en ambos dispositivos — converge en el mismo evento
wheel, haciendo que el desplazamiento sea el gesto más portátil para manejar:addEventListener("wheel", handler)captura tanto el desplazamiento con dos dedos en trackpad como la delegación de sobre-desplazamiento en pantalla táctil.
Esta división arquitectónica es intencional. El sistema operativo procesa los contactos múltiples crudos del touchpad y entrega eventos terminados y semánticamente etiquetados al navegador. El navegador luego reenvía esos eventos a las páginas. Una pantalla táctil, en cambio, pasa datos crudos de contacto al navegador, por eso el código web puede implementar lógica personalizada de pellizco en pantalla táctil pero no puede hacer lo mismo en un trackpad de escritorio sin salir de la plataforma web estándar.
Cómo el tester refleja este diseño
El módulo GestureDetector del tester usa esta división deliberadamente. Tap, doble tap, pulsación larga y deslizamiento se detectan mediante escuchas PointerEvent — los mismos eventos que un trackpad dispara como eventos pointerType: "mouse". El desplazamiento se detecta mediante escuchas de eventos wheel. El pellizco, sin embargo, se detecta mediante TouchEvent (touchstart, touchmove) — verificando específicamente dos contactos simultáneos y midiendo el cambio en la distancia entre ellos. Si la distancia cambia más de 30 píxeles, se activa un pellizco. En un trackpad de escritorio esta ruta nunca se dispara porque no llega ningún TouchEvent; el pellizco en trackpad llega al navegador solo como un evento ctrl+wheel, que el panel de gestos cuenta bajo desplazamiento en lugar de pellizco. En pantalla táctil, la ruta TouchEvent se dispara correctamente y el contador de pellizcos incrementa.
Una limitación práctica que vale la pena mencionar: ninguna API expone datos crudos de contacto de dedos desde un trackpad de escritorio a una página web. Una herramienta tester puede observar que se disparó un evento ctrl+wheel, pero no puede informar cuántos dedos lo produjeron ni las posiciones crudas de contacto — esa información la consume el sistema operativo antes de llegar al navegador.
Compruébalo tú mismo: usa la herramienta arriba en un touchpad de laptop y prueba un gesto de pellizco con dos dedos. Si el panel de detección de gestos no muestra aumento en el contador de pellizcos, estás en un trackpad de escritorio donde el pellizco llega comoctrl+wheelen lugar deTouchEvent. Cambia a un dispositivo con pantalla táctil y repite el gesto — el contador de pellizcos debería incrementarse, confirmando que la ruta de dos dedosTouchEventestá activa ahora.