auxclick llegará a Chrome 55

¿Cuándo un clic no es click? Para un desarrollador web que trabaja en una interfaz de usuario compleja, esa no es una pregunta filosófica y abstracta. Si implementas un comportamiento de entrada personalizado del mouse, es fundamental que tengas en cuenta el intent del usuario. Por ejemplo, si un usuario hace clic en un vínculo con el botón central del mouse, es razonable suponer que desea abrir una pestaña nueva con el contenido de ese vínculo. Si un usuario hace clic con el botón central en un elemento aleatorio de la IU, es posible que quieras suponer que fue involuntario y que ignorar esa entrada, mientras que un clic en el botón principal debería activar una respuesta de la IU.

Si es un poco engorroso, es posible modelar estas interacciones matizadas a través de un solo objeto de escucha de eventos click. Deberías verificar de forma explícita la propiedad button de MouseEvent para ver si se estableció en 0, que representa el botón principal, en lugar de cualquier otra cosa, en la que 1 suele representar el botón central, y así sucesivamente. Sin embargo, no muchos desarrolladores van a verificar explícitamente la propiedad button, lo que genera un código que controla todas las click de forma idéntica, sin importar qué botón se presionó.

A partir de Chrome 55, se activa un nuevo tipo de MouseEvent, llamado auxclick, en respuesta a cualquier clic que se haga con un botón no principal. Este evento nuevo acompaña el cambio correspondiente en el comportamiento del evento click: solo se activará cuando se presione el botón principal del mouse. Esperamos que estos cambios les permitan 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.

Reduce los falsos positivos

Como se mencionó, una motivación para crear auxclick fue evitar la implementación de controladores click personalizados que anulen por error el comportamiento "middle-click-opens-a-tab". 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....
});

Tu lógica personalizada podría funcionar según lo previsto cuando se activa con el botón principal de un mouse, pero si se ejecuta ese código cuando se hace clic en un botón central, en realidad es un falso positivo. Antes del nuevo comportamiento, debías impedir la acción predeterminada de abrir una pestaña nueva, lo que contradice las expectativas del usuario. Si bien puedes verificar explícitamente que se encuentre event.button === 0 al comienzo de tu controlador y solo ejecutar el código si ese es el caso, es fácil olvidarlo o nunca te das cuenta de que es necesario hacerlo.

Ejecuta solo el código que necesitas

La otra cara de 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 un código que necesita, por ejemplo, calcular una URL de destino adecuada antes de abrir una pestaña nueva, puedes detectar auxclick e 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.

Navegadores compatibles y compatibilidad

Por el momento, este nuevo comportamiento solo se implementa en Chrome 55. Como se mencionó en la propuesta inicial, se aprecian los comentarios (positivos y 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 amplia 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 manejará los clics principales y auxiliares de manera diferente, independientemente de 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);