¿Cuándo un clic no es un click
? Para un desarrollador web que trabaja en una interfaz de usuario compleja, esa no es una pregunta filosófica abstracta. Si implementas un comportamiento personalizado de entrada del mouse, es fundamental tener en cuenta la intención del usuario. Por ejemplo, si un usuario hace clic en un vínculo con el botón del medio del mouse, es razonable suponer que quería abrir una pestaña nueva con el contenido de ese vínculo. Si un usuario hace clic con el botón del medio en un elemento de la IU aleatorio, es posible que desees asumir que fue un error y, luego, ignorar esa entrada. Por el contrario, se espera que un clic en el botón principal active una respuesta de la IU.
Es posible, aunque un poco engorroso, modelar estas interacciones con matices a través de un solo objeto de escucha de eventos click
. Tendrías que verificar de forma explícita la propiedad button
de MouseEvent
para ver si se configuró como 0
, que representa el botón principal, en lugar de cualquier otra cosa, con 1
que suele representar el botón del medio, etcétera. Sin embargo, no muchos desarrolladores llegan al punto de verificar de forma explícita la propiedad button
, lo que genera un código que controla todos los click
de forma idéntica, independientemente de qué botón se presionó.
A partir de Chrome 55, se activa un nuevo tipo de MouseEvent
, llamado auxclick
, en respuesta a los clics que se realizan con un botón que no es el principal. Junto con este nuevo evento, se produce un cambio correspondiente en el comportamiento del evento click
: solo se activará cuando se presione el botón principal del mouse. Esperamos que estos cambios faciliten a los desarrolladores web escribir controladores de eventos que respondan solo al tipo de clics que les interesan, sin tener que verificar específicamente la propiedad MouseEvent.button
.
Reducir los falsos positivos
Como se mencionó, una motivación para crear auxclick
fue evitar la implementación de controladores click
personalizados que anulan por error el comportamiento "hacer clic con el botón del medio para abrir una pestaña". Por ejemplo, imagina que escribiste un controlador de eventos click
que usa la API de History para reescribir la barra de ubicación y, luego, implementar navegaciones personalizadas de una sola página. Podría verse de la siguiente manera:
document.querySelector('#my-link').addEventListener('click', event => {
event.preventDefault();
// ...call history.pushState(), use client-side rendering, etc....
});
Es posible que tu lógica personalizada funcione según lo previsto cuando se activa con el botón principal del mouse, pero si ese código se ejecuta cuando se hace clic en el botón del medio, es un falso positivo. Antes del nuevo comportamiento, evitarías la acción predeterminada de abrir una pestaña nueva, lo que va en contra de las expectativas de los usuarios.
Si bien podrías verificar event.button === 0
de forma explícita al comienzo de tu controlador y solo ejecutar el código si ese es el caso, es fácil olvidarlo o nunca darte cuenta de que es necesario hacerlo.
Ejecuta solo el código que necesitas
La desventaja de tener menos falsos positivos es que las devoluciones de llamada de auxclick
solo se ejecutarán cuando se haga clic en un botón del mouse que no sea el principal. Si tienes código
que debe, por ejemplo, calcular una URL de destino adecuada antes de
abrir una pestaña nueva, puedes detectar auxclick
y, luego, incluir esa lógica en tu
devolución de llamada. No incurrirá en la sobrecarga de ejecutarse cuando se haga clic en el botón principal del mouse.
Compatibilidad y compatibilidad del navegador
Actualmente, este nuevo comportamiento solo se implementa en Chrome 55. Como se mencionó en la propuesta inicial, agradecemos los comentarios (tanto positivos como negativos) de la comunidad de desarrolladores web. Informar un problema de GitHub es la mejor manera de compartir esos comentarios con las personas que trabajan en el proceso de estandarización.
Mientras tanto, los desarrolladores no tienen que esperar a que auxclick
esté disponible de forma general para seguir algunas prácticas recomendadas para controlar los eventos del mouse. Si te tomas el tiempo de verificar el valor de la propiedad MouseEvent.button
al comienzo de tu controlador de eventos click
, puedes asegurarte de tomar las medidas adecuadas. El siguiente patrón controlará los clics primarios y auxiliares de manera diferente, ya sea que haya compatibilidad nativa con auxclick
o no:
function handlePrimaryClick(event) {
// ...code to handle the primary button click...
}
function handleAuxClick(event) {
// ...code to handle the auxiliary button click….
}
document.querySelector('#my-link').addEventListener('click', event => {
if (event.button === 0) {
return handlePrimaryClick(event);
}
// This provides fallback behavior in browsers without auxclick.
return handleAuxClick(event);
});
// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);