Zo voorkom je dat toetsenbordbediening een met de muis bestuurde puzzelschuif verstoort
Als je een browsergebaseerde schuifpuzzel bouwt als hulpmiddel bij een tafelavontuur, laat de muissleepbeweging en toetsenbordbediening dan dezelfde puzzelstatus gebruiken en beperk sneltoetsen tot de puzzel. De belangrijkste aandachtspunten zijn focus, gebeurtenisafhandeling en het afronden van sleepbewegingen: een toetsaanslag in een tekstveld mag geen tegel verplaatsen, en een sleepbeweging mag niet worden onderbroken of verloren gaan wanneer de aanwijzer een tegelgrens passeert.
Bepaal eerst waardoor de puzzel onverwacht beweegt
Wanneer een puzzel tijdens een muisactie reageert op een pijltjestoets, ligt dat vaak aan een te breed ingestelde toetsenbordlistener. Een handler die aan document of window is gekoppeld, kan pijltjestoetsen ontvangen terwijl de speler in een aanwijzingsveld typt, een menu gebruikt of een ander bedieningselement bedient. De handler kan ook browsergedrag activeren, zoals scrollen, terwijl de puzzel tegelijkertijd verandert.
Reproduceer het probleem aan de hand van een korte checklist: klik op een tegel en sleep die; sleep over de rand van de puzzel; druk op een pijltjestoets wanneer de puzzel focus heeft; druk er daarna op wanneer een invoerveld voor aanwijzingen, knop of menu focus heeft. Noteer of het bord verandert, de pagina scrolt, de focus verplaatst of het slepen stopt. Zo kun je onderscheid maken tussen een probleem met de puzzelhandler, aanwijzertracking of standaard browsergedrag.
Geef de puzzel een duidelijke focusgrens
Behandel het bord als een bedieningselement met een duidelijk instappunt voor toetsenbordbediening. Gebruik een focusbare bordcontainer en verwerk puzzeltoetsen alleen wanneer dat bord actief is of wanneer de focus op een tegel staat die bij het bord hoort. Houd niet-gerelateerde bedieningselementen, zoals hintknoppen en tekstvelden, buiten die grens voor toetsafhandeling. Maak zichtbaar waar de focus zich bevindt, zodat de speler weet wanneer het bord reageert.
Controleer het gebeurtenisdoel voordat je een toets interpreteert. Als de focus in een invoerveld, tekstgebied, bewerkbaar element of afzonderlijke knop staat, laat de toets dan ongemoeid. Dit is belangrijk voor een gezamenlijk avonturenspelhulpmiddel wanneer de ene speler een runenteken, naam of aanwijzing invoert terwijl iemand anders de puzzel bedient: typen mag niet per ongeluk tegels verplaatsen.
Toetsenbordbediening moet wel blijven werken. In de richtlijnen van het W3C staat dat functionaliteit waar mogelijk via een toetsenbordinterface beschikbaar moet zijn. Ook wordt het verplaatsen van objecten naar een locatie genoemd als een actie die met het toetsenbord kan worden uitgevoerd. Beperk de toetsen zorgvuldig in plaats van ze helemaal te verwijderen. W3C: Understanding Success Criterion 2.1.1: Keyboard
Scheid puzzelopdrachten van standaard browsergedrag
Kies een kleine, gedocumenteerde set toetsen voor het bord, zoals de pijltjestoetsen wanneer het bord focus heeft. Controleer in de handler eerst of de toets door de puzzel wordt gebruikt en of het bord het actieve doel is. Voer pas daarna de zet uit en annuleer, indien nodig, de standaardactie van de browser voor die toets. Onderdruk niet overal alle toetsen: spelers hebben mogelijk gewone tekstinvoer, browsernavigatie en bedieningselementen buiten de puzzel nodig.
preventDefault() annuleert een standaard browseractie wanneer de gebeurtenis annuleerbaar is, maar voorkomt niet dat de gebeurtenis zich naar andere handlers verspreidt. Zo kun je scrollen op de pagina voorkomen zonder een tweede listener uit te schakelen die ook een tegel verplaatst. Zoek de handler die de spelstatus wijzigt en beperk het bereik ervan; gebruik algemene annulering niet als vervanging voor duidelijk eigenaarschap van gebeurtenissen. MDN: Event: preventDefault() method
Zorg dat slepen met de aanwijzer op het hele bord blijft werken
Volg bij een sleepactie één actieve aanwijzer vanaf de druk waarmee het slepen begint tot het loslaten of annuleren ervan. Pointer Events bieden pointerdown, pointermove, pointerup en pointercancel; pointer capture kan ervoor zorgen dat latere aanwijzergebeurtenissen naar het bord worden gestuurd, ook wanneer de aanwijzer buiten het oorspronkelijke raakgebied komt. Wis de actieve sleepstatus bij zowel pointerup als pointercancel, zodat een onderbroken beweging de puzzel niet in een vastgelopen sleepstatus achterlaat. MDN: Pointer events
Vermijd het opnieuw opbouwen of vervangen van de gesleepte tegel op een manier waardoor de tracking van de aanwijzer verloren gaat. Als de interface tijdens het slepen een element in de DOM verplaatst, merkt MDN op dat pointer capture na die verplaatsing moet worden ingesteld. Bepaal wat er gebeurt wanneer de aanwijzer op een ongeldige positie wordt losgelaten: bij een schuifpuzzel is het begrijpelijker om de tegel naar de vorige positie terug te zetten of naar een geldige positie te laten springen dan om ongemerkt andere tegels te verplaatsen.
Maak dezelfde zet mogelijk zonder slepen
Een puzzel kan muis-, toetsenbord- en eenvoudige aanwijzerbediening combineren. Je kunt bijvoorbeeld een tegel naast de lege plek verplaatsen door erop te klikken of te tikken; slepen kan een optionele directe bediening blijven; en pijltjestoetsen met focus op het bord kunnen toetsenbordbediening bieden. Al deze invoermethoden moeten dezelfde logica voor zetvalidatie aanroepen, zodat een zet altijd op dezelfde manier geldig is of wordt afgewezen.
Dit levert ook een nuttige ontwerpcontrole op: kan een speler de puzzel voltooien door te klikken of tikken, zonder te slepen? De WCAG 2.2-richtlijnen van het W3C behandelen toetsenbordtoegang en een alternatief met één aanwijzer voor sleepbewegingen als afzonderlijke aandachtspunten. De voorbeelden omvatten het vervangen van slepen door klikken op richtingsknoppen. Een alternatief dat alleen met het toetsenbord werkt, biedt op zichzelf geen alternatief met een aanwijzer. W3C: Understanding Success Criterion 2.5.7: Dragging Movements
Bij een schuifpuzzel is telkens op één aangrenzende tegel klikken vaak een natuurlijk alternatief, omdat de regel voor aangrenzende zetten zo behouden blijft. Als die interactie onduidelijk zou zijn, kunnen zichtbare zetknoppen de beschikbare richting aangeven. De techniek G219 van het W3C bevat voorbeelden van bedieningselementen met één aanwijzer die dezelfde onderliggende actie uitvoeren zonder te slepen. W3C: G219: Ensuring that an alternative is available for dragging movements that operate on content
Test met een korte invoermatrix
Loop voordat je de puzzel aan tafel gebruikt elke invoermethode door met dezelfde bordindeling en beginstatus. Controleer of een geldige zet het bord één keer bijwerkt, een ongeldige zet het bord ongemoeid laat en niet-gerelateerde bedieningselementen zich normaal blijven gedragen.
Muis: sleep een geldige tegel, laat die buiten het bord los en probeer een ongeldige zet. Controleer dat het bord de sleepbeweging niet kwijtraakt en niet onverwacht verandert.
Toetsenbord: geef het bord focus en gebruik elke ondersteunde richting. Verplaats daarna de focus naar een tekstveld en typ. Controleer dat alleen toetsen met focus op het bord tegels verplaatsen en dat typen het bord niet laat scrollen of veranderen.
Aanwijzer zonder slepen: klik of tik op een geldige aangrenzende tegel. Controleer of dit dezelfde zet oplevert als de andere invoermethoden.
Onderbreking: annuleer of beëindig een sleepbeweging en start daarna een nieuwe. Controleer dat er geen oude selectie achterblijft.
Als een test mislukt, controleer dan eerst de meest relevante laag: het gebeurtenisdoel en de focusstatus bij toetsenbordgedrag; pointer capture en opruiming bij onderbroken sleepbewegingen; en de gedeelde zetvalidator bij inconsistente regels. Zo krijgt de bouwer een concrete manier om het probleem te vinden, zonder van het avonturenattribuut een algemene bedieningshandleiding te maken.
