Wanneer is een klik geen click
? Voor een webontwikkelaar die aan een complexe gebruikersinterface werkt, is dat geen abstracte filosofische vraag. Als u aangepast muisinvoergedrag implementeert, is het van cruciaal belang om de intentie van de gebruiker in gedachten te houden. Als een gebruiker bijvoorbeeld met de middelste muisknop op een link klikt, is het redelijk om aan te nemen dat hij een nieuw tabblad wilde openen met de inhoud van die link. Als een gebruiker met de middelste muisklik op een willekeurig UI-element klikt, kunt u ervan uitgaan dat dit onbedoeld was en die invoer negeren, terwijl van een primaire klik op de knop zou worden verwacht dat deze een reactie van de UI zou activeren.
Het is, als het een beetje omslachtig is, mogelijk om deze genuanceerde interacties te modelleren via een gebeurtenislistener met één click
. Je zou expliciet de button
eigenschap van MouseEvent
moeten controleren om te zien of deze is ingesteld op 0
, wat de primaire knop vertegenwoordigt, versus iets anders, waarbij 1
meestal de middelste knop vertegenwoordigt, enzovoort. Maar niet veel ontwikkelaars gaan zo ver dat ze de button
expliciet controleren, wat leidt tot code die alle click
op dezelfde manier afhandelt, ongeacht op welke knop werd gedrukt.
Vanaf Chrome 55 wordt een nieuw type MouseEvent
, genaamd auxclick
, geactiveerd als reactie op klikken die worden gemaakt met een niet-primaire knop. Deze nieuwe gebeurtenis gaat gepaard met een overeenkomstige verandering in het gedrag van de click
: deze wordt alleen geactiveerd als de primaire muisknop wordt ingedrukt. We hopen dat deze wijzigingen het voor webontwikkelaars gemakkelijker zullen maken om gebeurtenishandlers te schrijven die alleen reageren op het type klik dat hen interesseert, zonder dat ze specifiek de eigenschap MouseEvent.button
hoeven te controleren.
Verminder valse positieven
Zoals gezegd was een motivatie voor het maken van auxclick
het vermijden van de inzet van aangepaste click
die per ongeluk het gedrag van 'middelste klik-opent-een-tab' overschrijven. Stel je voor dat je een click
hebt geschreven die de History API gebruikt om de locatiebalk te herschrijven en aangepaste navigatie op één pagina te implementeren. Het zou er ongeveer zo uit kunnen zien:
document.querySelector('#my-link').addEventListener('click', event => {
event.preventDefault();
// ...call history.pushState(), use client-side rendering, etc....
});
Uw aangepaste logica werkt mogelijk zoals bedoeld wanneer deze wordt geactiveerd door de primaire knop van een muis, maar als die code wordt uitgevoerd wanneer op een middelste knop wordt geklikt, is dit in feite een vals-positief resultaat. Voorafgaand aan het nieuwe gedrag verhinderde u uiteindelijk de standaardactie om een nieuw tabblad te openen, wat in strijd is met de verwachtingen van uw gebruiker. Hoewel je expliciet zou kunnen controleren op event.button === 0
aan het begin van je handler, en de code alleen zou kunnen uitvoeren als dat het geval is, is het gemakkelijk om het te vergeten, of je nooit te realiseren dat het nodig is om dat te doen.
Voer alleen de code uit die u nodig hebt
De keerzijde van minder valse positieven is dat auxclick
callbacks alleen worden uitgevoerd als er daadwerkelijk op een niet-primaire muisknop wordt geklikt. Als u code heeft die bijvoorbeeld een geschikte bestemmings-URL moet berekenen voordat u een nieuw tabblad opent, kunt u luisteren naar auxclick
en die logica opnemen in uw callback. Het zal niet de overhead met zich meebrengen dat het wordt uitgevoerd wanneer op de primaire muisknop wordt geklikt.
Browserondersteuning en compatibiliteit
Dit nieuwe gedrag wordt momenteel alleen geïmplementeerd in Chrome 55. Zoals vermeld in het oorspronkelijke voorstel , wordt feedback (zowel positief als negatief) van de webontwikkelaarsgemeenschap op prijs gesteld. Het indienen van een GitHub-probleem is de beste manier om die feedback te delen met de mensen die aan het standaardisatieproces werken.
In de tussentijd hoeven ontwikkelaars niet te wachten tot auxclick
algemeen beschikbaar is om enkele best practices voor het omgaan met muisgebeurtenissen te volgen. Als u de tijd neemt om de waarde van de eigenschap MouseEvent.button
aan het begin van uw click
te controleren, kunt u ervoor zorgen dat u de juiste actie onderneemt. Het volgende patroon verwerkt primaire en aanvullende klikken op een andere manier, ongeacht of er native ondersteuning is voor 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);