O Auxclick está chegando ao Chrome 55

Quando um clique não é um click? Para um desenvolvedor da Web que trabalha em uma interface do usuário complexa, essa não é uma pergunta filosófica abstrata. Se você estiver implementando um comportamento personalizado de entrada do mouse, é essencial considerar a intent do usuário. Se um usuário clica em um link com o botão do meio do mouse, por exemplo, é razoável presumir que ele quer abrir uma nova guia com o conteúdo desse link. Se um usuário clica com o botão do meio em um elemento aleatório da interface, é possível presumir que ele foi acidental e ignorar essa entrada, enquanto um clique no botão principal precisa acionar uma resposta da interface.

É possível modelar essas interações detalhadas usando um único listener de eventos click. Você precisaria verificar explicitamente a propriedade button do MouseEvent para ver se ela estava definida como 0, representando o botão principal, em vez de qualquer outra coisa, com 1 geralmente representando o botão do meio e assim por diante. Porém, poucos desenvolvedores verificam explicitamente a propriedade button, levando a um código que processa todos os clicks de maneira idêntica, independente de qual botão foi pressionado.

A partir do Chrome 55, um novo tipo de MouseEvent, chamado auxclick, é acionado em resposta a cliques feitos com um botão não principal. Acompanhando esse novo evento, há uma mudança correspondente no comportamento do evento click: ele só será disparado quando o botão principal do mouse for pressionado. Esperamos que essas mudanças facilitem a criação de manipuladores de eventos que respondem apenas ao tipo de clique importante, sem a necessidade de verificar especificamente a propriedade MouseEvent.button.

Reduza falsos positivos

Como mencionado, uma das motivação para criar auxclick foi evitar a implantação de gerenciadores click personalizados que substituem erroneamente o comportamento "middle-click-opens-a-tab". Por exemplo, imagine que você tenha escrito um manipulador de eventos click que usa a API History para reescrever a barra de local e implementar navegações personalizadas de página única. Ela pode ser semelhante a esta:

document.querySelector('#my-link').addEventListener('click', event => {
    event.preventDefault();
    // ...call history.pushState(), use client-side rendering, etc....
});

Sua lógica personalizada pode funcionar conforme o esperado quando acionada pelo botão principal de um mouse, mas se esse código for executado quando um botão do meio for clicado, ele será um falso positivo. Antes do novo comportamento, você precisava impedir a ação padrão de abrir uma nova guia, o que vai contra as expectativas do usuário. Embora seja possível verificar explicitamente o event.button === 0 no início do gerenciador e executar o código apenas se esse for o caso, se for fácil esquecer ou nunca perceber que é necessário fazer isso.

Execute apenas o código necessário

Por outro lado, há menos falsos positivos: os callbacks auxclick só serão executados quando houver um clique do botão do mouse não principal. Se você tem um código que precisa, por exemplo, calcular um URL de destino adequado antes de abrir uma nova guia, detecte auxclick e inclua essa lógica no callback. Ele não vai sobrecarregar a execução quando o botão principal do mouse for clicado.

Compatibilidade e suporte a navegadores

Esse novo comportamento só está implementado no Chrome 55. Como mencionado na proposta inicial, o feedback (positivo e negativo) da comunidade de desenvolvedores da Web é agradecido. Registrar um problema no GitHub é a melhor maneira de compartilhar esse feedback com as pessoas que estão trabalhando no processo de padronização.

Enquanto isso, os desenvolvedores não precisam esperar que o auxclick seja amplamente disponibilizado para seguir algumas práticas recomendadas do gerenciamento de eventos de mouse. Se você reservar algum tempo para verificar o valor da propriedade MouseEvent.button no início do seu manipulador de eventos click, será possível tomar as medidas adequadas. O padrão a seguir processará os cliques primários e auxiliares de forma diferente, independentemente de haver ou não suporte nativo para auxclick:

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);