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