Apuntar a objetos en la Web solía ser simple. Tenías un mouse, lo moviste a veces presionaban botones, y eso fue todo. Todo lo que no fuera mouse se emulaba como uno, y los desarrolladores sabían exactamente con qué contar.
Sin embargo, simple no necesariamente significa bueno. Con el tiempo, se volvió cada vez más importante que no todo fuera (o fingiera ser) un mouse: podías tener bolígrafos sensibles a la presión y compatibles con la inclinación, para brindar una increíble libertad creativa podrías usarías los dedos, por lo que todo lo que necesitabas era el dispositivo y tu mano; y bueno, ¿por qué no uses más de un dedo mientras lo haces?
Tuvimos eventos táctiles. para ayudarnos con eso, pero son una API completamente independiente específicamente para el tacto, lo que te obliga a codificar dos modelos de eventos separados si admitir el mouse y el tacto. Chrome 55 se envía con un estándar más nuevo que unifica ambos modelos: eventos de puntero.
Un modelo de evento único
Los eventos de puntero unifican el modelo de entrada de puntero para el navegador, que combina la función táctil, los bolígrafos y los mouses en un solo conjunto de eventos. Por ejemplo:
document.addEventListener('pointermove',
ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
ev => console.log('The pointer is now over foo.'));
Esta es una lista de todos los eventos disponibles, que debería resultarte familiar si estás familiarizado con los eventos del mouse:
pointerover
|
El puntero ingresó en el cuadro delimitador del elemento.
Esto sucede inmediatamente en los dispositivos que permiten colocar el cursor sobre un elemento o antes de
pointerdown para los dispositivos que no lo hacen.
|
pointerenter
|
Es similar a pointerover , pero no muestra burbujas ni controladores.
y sus elementos subordinados
de forma diferente.
Detalles sobre la especificación
|
pointerdown
|
El puntero ingresó al estado del botón activo, y cualquiera de los dos presionado o que se establezca el contacto, según la semántica de la dispositivo de entrada. |
pointermove
|
El puntero cambió de posición. |
pointerup
|
El puntero salió del estado del botón activo. |
pointercancel
|
Se produjo un error, lo que significa que es poco probable que el puntero emita alguna o más eventos. Esto significa que debes cancelar cualquier acción en curso y continuar a un estado de entrada neutral. |
pointerout
|
El puntero salió del cuadro delimitador del elemento o la pantalla. También después de un
pointerup , si el dispositivo no permite colocar el cursor sobre un elemento
|
pointerleave
|
Es similar a pointerout , pero no muestra burbujas ni controladores.
y sus elementos subordinados
de forma diferente.
Detalles sobre la especificación
|
gotpointercapture
|
El elemento recibió captura de puntero. |
lostpointercapture
|
El puntero que se estaba capturando lanzamiento. |
Diferentes tipos de entrada
En general, los eventos de puntero te permiten escribir código de manera independiente de la entrada
sin tener que registrar controladores de eventos separados
para los distintos dispositivos de entrada.
Por supuesto, aún deberás tener en cuenta las diferencias entre los tipos de entrada, por ejemplo,
se aplica el concepto de colocar el cursor sobre un elemento. Si quieres diferenciar diferentes tipos de dispositivos de entrada, quizás para proporcionar
código o funcionalidad independientes para diferentes entradas; sin embargo, puedes hacerlo desde
dentro de los mismos controladores de eventos con la propiedad pointerType
del
PointerEvent
interfaz de usuario. Por ejemplo, si estuvieras programando un panel lateral de navegación, podrías
tener la siguiente lógica en tu evento pointermove
:
switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}
Acciones predeterminadas
En los navegadores con opciones táctiles, se usan ciertos gestos para hacer que la página se desplace, haga zoom o se actualice.
En el caso de los eventos táctiles, seguirás recibiendo eventos mientras estos eventos
se producen acciones. Por ejemplo, se seguirá activando touchmove
mientras el usuario se desplaza.
Con los eventos del puntero, cada vez que se activa una acción predeterminada, como el desplazamiento o el zoom,
recibirás un evento pointercancel
que te informará que el navegador completó
control del puntero. Por ejemplo:
document.addEventListener('pointercancel',
ev => console.log('Go home, the browser is in charge now.'));
Velocidad integrada: Este modelo proporciona un mejor rendimiento de forma predeterminada. en comparación con los eventos táctiles, en los que necesitarías usar objetos de escucha de eventos pasivos para lograr el mismo nivel de capacidad de respuesta.
Puedes impedir que el navegador tome el control con la
touch-action
propiedad de CSS. Si se establece en none
en un elemento, se inhabilitarán todos
acciones definidas por el navegador
que se inician sobre ese elemento. Pero hay varios
otros valores para un control más detallado, como pan-x
, para permitir
el navegador reaccione al movimiento en el eje x, pero no en el eje y. Chrome 55
admite los siguientes valores:
auto
|
Predeterminado; el navegador puede realizar cualquier acción predeterminada. |
none
|
El navegador no puede realizar ninguna acción predeterminada. |
pan-x
|
El navegador solo puede realizar la acción predeterminada de desplazamiento horizontal. |
pan-y
|
El navegador solo puede realizar la acción predeterminada de desplazamiento vertical. |
pan-left
|
El navegador solo puede realizar la acción predeterminada de desplazamiento horizontal y solo desplazar la página hacia la izquierda. |
pan-right
|
El navegador solo puede realizar la acción predeterminada de desplazamiento horizontal y solo desplazar la página hacia la derecha. |
pan-up
|
El navegador solo puede realizar la acción predeterminada de desplazamiento vertical y solo para desplazar la página hacia arriba. |
pan-down
|
El navegador solo puede realizar la acción predeterminada de desplazamiento vertical y solo desplazar la página hacia abajo. |
manipulation
|
El navegador solo puede realizar acciones de desplazamiento y zoom. |
Captura del puntero
¿Alguna vez pasaste una hora frustrante para depurar un mouseup
dañado?
hasta que te diste cuenta de que es porque el usuario suelta el botón
fuera de tu objetivo de clics? ¿No? Bueno, quizás solo seré yo.
Sin embargo, hasta ahora no había una forma realmente buena de abordar este problema. Claro,
puedes configurar el controlador mouseup
en el documento y guardar algún estado en
tu aplicación para hacer un seguimiento de los aspectos. Esa no es la solución más limpia,
sobre todo si desea crear un componente web y tratar de que todo esté lindo y
aisladas.
Los eventos de puntero son una solución
mucho mejor: puedes capturar el puntero,
para asegurarte de obtener ese evento pointerup
(o cualquier otro de sus eventos elusivos
amigos).
const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
console.log('Button down, capturing!');
// Every pointer has an ID, which you can read from the event.
foo.setPointerCapture(ev.pointerId);
});
foo.addEventListener('pointerup',
ev => console.log('Button up. Every time!'));
Navegadores compatibles
Al momento de la redacción, los eventos de puntero son compatibles con Internet Explorer 11, Microsoft Edge, Chrome y Opera, y parcialmente compatibles con Firefox. Puedes Encuentra una lista actualizada en caniuse.com.
Puedes usar el polyfill de eventos de puntero para lo siguiente: para llenar los vacíos. Como alternativa, comprobar la compatibilidad del navegador en el tiempo de ejecución sencillo:
if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}
Los eventos de puntero
son un gran candidato para la mejora progresiva:
modifica tus métodos de inicialización para hacer la verificación anterior, agrega un evento de puntero
en el bloque if
y mueve los controladores de eventos de mouse/táctil al
Bloque else
.
Así que no dejes de probarlos y contarnos tu opinión.