JavaScript-events en interactieve pagina's
BeginnerLes 6 van 9 in Cursus JavaScript programmeren: DOM, events, asynchrone code en modules
Wat je leert
- Laat een pagina reageren wanneer er iets gebeurt: koppel listeners aan elementen, lees wat het eventobject meldt en bepaal hoelang elke listener actief blijft.
- Koppel een eventlistener aan een elementGebruik
addEventListenerom een functie uit te voeren telkens wanneer op een element een klik, toetsaanslag, formulieractie of pagina-event plaatsvindt. - Lees de informatie in het eventobjectGebruik het eventobject dat een listener ontvangt om te achterhalen wat er is gebeurd en waar: het type, doel, huidige doel en eventspecifieke details.
- Verwijder eventlisteners en bepaal hoe ze worden uitgevoerdStop met luisteren als een listener niet meer nodig is, gebruik de opties
once,signalenpassiveen laat je eigen events afgaan.
- Koppel een eventlistener aan een element
- Leg uit hoe een event omlaag naar het doel en weer omhoog door de pagina gaat, annuleer ingebouwd browsergedrag wanneer je het vervangt en gebruik opwaartse eventpropagatie om meerdere elementen met één listener af te handelen.
- Leg opwaartse eventpropagatie en de opvangfase uitBeschrijf de drie fasen van eventpropagatie en voorspel in welke volgorde listeners op geneste elementen worden uitgevoerd.
- Voorkom standaardacties en stop eventpropagatieAnnuleer de ingebouwde reactie van de browser op een event wanneer je code die vervangt, en voorkom alleen dat een event verder gaat als dat echt nodig is.
- Handel events van meerdere elementen af met eventdelegatieGebruik één listener op een gedeelde voorouder en
event.target.closest()om events van meerdere kindelementen af te handelen, inclusief elementen die later zijn toegevoegd.
- Leg opwaartse eventpropagatie en de opvangfase uit
- Reageer op toetsaanslagen, focuswijzigingen, klikken, aanrakingen en peninvoer en bouw een sleepinteractie die met elke soort aanwijzer werkt.
- Reageer op toetsaanslagen en focuswijzigingenGebruik
keydown,keyupen de focusevents, kies tussenevent.keyenevent.codeen bouw sneltoetsen die de gebruiker niet in de weg zitten. - Verwerk klikken, aanrakingen en peninvoer met pointereventsGebruik
clickvoor activering en pointerevents voor indrukken, bewegen en loslaten met een muis, vinger of pen; lees coördinaten en knoppen uit en kies de juiste events voor aanwijzen. - Bouw een sleepinteractie met pointereventsCombineer
pointerdown,pointermoveenpointerupmet het vastleggen van de aanwijzer om een element te verplaatsen, laat dit werken op touchscreens en bied een manier om hetzelfde te doen zonder te slepen.
- Reageer op toetsaanslagen en focuswijzigingen
- Lees wat gebruikers invoeren terwijl ze typen, handel formulierverzending af in JavaScript en controleer invoer met de validatiefuncties van de browser en je eigen regels, met duidelijke foutmeldingen.
- Lees formuliervelden uit en reageer terwijl gebruikers typenLees tekstvelden, getallen, selectievakjes, keuzerondjes en keuzelijsten uit, gebruik de events
inputenchangeop het juiste moment en verzamel een volledig formulier metFormData. - Handel formulierverzending af in JavaScriptLuister naar het
submit-event van het formulier, voorkom dat de pagina opnieuw wordt geladen, lees de verzonden gegevens en weet wat een verzending in gang zet. - Gebruik de ingebouwde validatie van de browserBeschrijf regels met HTML-attributen, lees het resultaat uit het
validity-object, controleer velden vanuit code en geef ongeldige velden op het juiste moment een andere stijl. - Schrijf eigen validatie met duidelijke foutmeldingenVoeg regels toe die de HTML-attributen niet kunnen uitdrukken, schrijf behulpzame meldingen, toon ze op het juiste moment en koppel ze aan hun velden.
- Lees formuliervelden uit en reageer terwijl gebruikers typen
- Maak interactieve elementen die met een muis, toetsenbord en schermlezer werken: geef de voorkeur aan ingebouwde HTML-elementen, voeg rollen, toetsenbordbediening en status toe wanneer je zelf elementen bouwt en houd de focus waar gebruikers die verwachten.
- Geef de voorkeur aan ingebouwde HTML-elementen en maak eigen bedieningselementen focusbaarWeet wat ingebouwde interactieve elementen je vanzelf bieden en wat je aan een eigen bedieningselement van een
<div>of<span>moet toevoegen: een rol, focusbaarheid, een toegankelijke naam en een zichtbare focusindicator. - Voeg toetsenbordbediening en statusinformatie toe aan eigen bedieningselementenLaat eigen knoppen, schakelknoppen, uitklapcomponenten, selectievakjes en groepen items met het toetsenbord werken en houd hun ARIA-status gelijk aan wat gebruikers zien.
- Houd de focus waar gebruikers die verwachten wanneer de pagina verandertVerplaats de focus bewust wanneer inhoud opent, sluit, wordt verwijderd of fouten toont, en verplaats die nooit onverwacht terwijl gebruikers typen of kiezen.
- Geef de voorkeur aan ingebouwde HTML-elementen en maak eigen bedieningselementen focusbaar
JavaScript-events: uitleg
1Reageer op events met eventlisteners
Webpagina's reageren via functies die voor events zijn geregistreerd. Bij de installatie kies je het element en het eventtype; elke latere gebeurtenis levert een eventobject op dat beschrijft wat er is gebeurd. Door dat object uit te lezen kan een listener op het juiste bedieningselement reageren, ook als een klik op een pictogram daarbinnen terechtkomt. Met listenerreferenties en opties kan een functie haar reacties precies zo lang actief houden als nodig is, en met eigen events kan het ene deel van een pagina een ander deel informeren.
1.1 Listeners zetten acties om in code
Een pagina kan wachten totdat iemand iets doet. Een event meldt iets wat is gebeurd en een eventlistener is de functie die als reactie wordt aangeroepen. Door een listener te registreren stel je die reactie in; de actie wordt niet meteen uitgevoerd.
Voeg de functie toe aan het element
Selecteer een element dat al bestaat, kies de exacte naam van het event en geef een functie door:
const button = document.querySelector("#like");
let likes = 0;
button.addEventListener("click", function () {
likes = likes + 1;
button.textContent = "Likes: " + likes;
});
De selectie, het instellen van de variabele en de registratie worden uitgevoerd wanneer het script wordt uitgevoerd. Elke latere klik voert het functielichaam uit. Na drie klikken toont de knop “Likes: 3”. Door likes buiten de functie te houden blijft het totaal tussen klikken behouden; als je let likes = 0 binnen de functie zou zetten, zou de teller telkens opnieuw beginnen.
Geef een functiereferentie door, zoals showMenu, zonder haakjes. In button.addEventListener("click", showMenu()) roept JavaScript showMenu direct aan en geeft de retourwaarde door als listener. Om later een argument mee te geven, zet je de aanroep in een omhullende functie: button.addEventListener("click", () => showMenu("main"));.
Kies een event dat daadwerkelijk plaatsvindt
Namen zijn hoofdlettergevoelige strings zonder het voorvoegsel “on”. Gebruik "click", niet "Click" of "onclick". Een verzonnen naam wordt zonder foutmelding geaccepteerd, maar de browser zal die niet bij een klik laten afgaan. Veelvoorkomende families zijn pointerevents zoals pointerdown en pointerup, toetsenbordevents zoals keydown, formulierevents zoals input en submit, en focusevents zoals focusin. DOMContentLoaded heeft een eigen exacte schrijfwijze met hoofdletters.
Stel het juiste element op het juiste moment in
Een script in de head kan worden uitgevoerd voordat een knop bestaat. De selectie geeft dan null terug en een aanroep van addEventListener daarop veroorzaakt een fout. Laad een extern script met defer, plaats het na de opmaakcode of registreer de installatie bij het DOMContentLoaded-event van het document. Een element dat later wordt gemaakt, heeft na het maken installatie nodig of een listener op een voorouder.
querySelectorAll geeft een NodeList terug, niet één eventdoel. Registreer listeners op de elementen:
document.querySelectorAll(".tab").forEach((tab) => {
tab.addEventListener("click", selectTab);
});
Laat listeners naast elkaar bestaan
| Methode | Wat registratie doet |
|---|---|
addEventListener("click", fn) | Voegt een listener toe naast andere listeners en accepteert opties. |
button.onclick = fn | Vervangt de ene handler in de eigenschap; wijs null toe om die te wissen. |
Een HTML-attribuut onclick | Plaatst JavaScript in de opmaakcode. |
Listeners met dezelfde capture-instelling worden uitgevoerd in de volgorde van registratie. Op het eventdoel worden opvanglisteners vóór andere listeners uitgevoerd. Als je hetzelfde functieobject opnieuw toevoegt met hetzelfde type en dezelfde capture-instelling, wordt geen tweede exemplaar toegevoegd.
Belangrijkste punten
- Geef de functie zelf door; gebruik een omhullende functie als de latere aanroep argumenten nodig heeft.
- Eventnamen vereisen een exacte spelling en exact hoofdlettergebruik.
- Een element moet bestaan wanneer de listener ervan wordt geregistreerd.
- Doorloop een NodeList met een lus om listeners aan de elementen te koppelen.
addEventListenerstaat meerdere listeners toe; een eigenschap voor een eventhandler bevat er één.
1.2 Lees uit waar een event begon
De browser geeft een eventobject door aan je listener. De eigenschappen ervan verklaren het event dat deze specifieke aanroep veroorzaakte. Noem de parameter event of e; de parameternaam kies je zelf.
button.addEventListener("click", (event) => {
console.log(event.type);
console.log(event.currentTarget);
});
Dit schrijft "click" en de knop naar de console tijdens de aanroep van de listener. Door het hele object naar de console te schrijven kun je de andere eigenschappen ontdekken.
Onderscheid de oorsprong van de listener
Stel je een knop voor die een afbeelding bevat:
<button id="save" data-id="7">
<img src="disk.svg" alt=""> Save
</button>
| Eigenschap | Betekenis | Bij een klik op de afbeelding |
|---|---|---|
event.target | Waar het event begon | De afbeelding |
event.currentTarget | Waar de actieve listener is gekoppeld | De knop, bij een listener op de knop |
Een klik op de tekst “Save” maakt ook de knop tot doel. De tekst is onderdeel van de knop; die wordt geen afzonderlijk doelelement.
Dit verschil is belangrijk bij het uitlezen van gegevens. De afbeelding heeft niet de data-id van de knop, dus event.target.dataset.id is undefined bij een klik op de afbeelding. Een listener die direct aan de knop is gekoppeld, kan event.currentTarget.dataset.id uitlezen. Een listener op een grotere container kan de bedoelde knop vinden met event.target.closest("button") en controleren of er een overeenkomst is.
Lees de details van dit event
Elk event heeft een type, een target en een currentTarget. De booleaanse waarde bubbles geeft aan of het event weer omhoog via voorouders gaat. cancelable geeft aan of code de standaardactie mag annuleren en defaultPrevented houdt bij of die annulering heeft plaatsgevonden. timeStamp legt het tijdstip waarop het event is gemaakt vast in milliseconden ten opzichte van de tijdsoorsprong van de pagina.
Verschillende eventfamilies voegen nuttige details toe. Een moderne click levert een PointerEvent op, dat eigenschappen van muisevents overerft, zoals clientX, clientY en button. Een KeyboardEvent voegt key, code en vlaggen voor modificatietoetsen toe. Een input-listener kan event.target.value gebruiken om de nieuwe tekst van het veld uit te lezen.
Voor een galerijlistener kan event.target.tagName gelijk zijn aan "IMG" wanneer op een foto wordt geklikt, of aan "DIV" wanneer op de tussenruimte wordt geklikt. Handel het werkelijk gemelde geval af. Ga er niet van uit dat elk event binnen een container van hetzelfde soort kind komt.
Gebruik de waarde terwijl de listener wordt uitgevoerd
In een listener die een gewone functie is, is this gelijk aan event.currentTarget. Een pijlfunctie neemt this over uit de omringende code; die krijgt het element niet als this. event.currentTarget werkt bij beide functievormen.
Na de eventafhandeling wordt currentTarget teruggezet op null. Een console kan die latere waarde tonen wanneer je een eerder naar de console geschreven event uitklapt. Schrijf event.currentTarget direct binnen de listener naar de console om het element tijdens de aanroep te bekijken.
Belangrijkste punten
targetgeeft de oorsprong van het event aan;currentTargetgeeft het element van de actieve listener aan.- Lees gegevens uit het element dat ze daadwerkelijk bevat.
- Eventfamilies voegen eigenschappen toe zoals coördinaten, toetswaarden en modificatietoetsen.
currentTargetis beschikbaar tijdens de listener en wordt daarnanull.
1.3 Bepaal hoelang een listener actief blijft
Een listener moet actief blijven zolang de bijbehorende functie die nodig heeft. Bewaar bij een tijdelijke toetsenbordinteractie de functiereferentie, zodat je de listener kunt verwijderen wanneer de interactie sluit.
Verwijder dezelfde functie
function onKey(event) {
console.log(event.key);
}
document.addEventListener("keydown", onKey);
// When the feature closes:
document.removeEventListener("keydown", onKey);
Bij het verwijderen moeten het eventtype, het functieobject en de capture-instelling overeenkomen. Ook een anonieme functie kun je verwijderen wanneer de referentie is bewaard, zoals in const handler = () => save();. Als je een nieuwe () => save() schrijft in de aanroep om de listener te verwijderen, maak je een andere functie, ook al ziet de code er identiek uit.
Kies de registratieopties
| Optie | Effect |
|---|---|
once: true | Verwijdert deze listener na de eerste aanroep. |
signal: controller.signal | Verwijdert de listener wanneer die controller wordt afgebroken. |
capture: true | Luistert op de weg omlaag tijdens de opvangfase. |
passive: true | Geeft aan dat de listener de standaardactie niet zal annuleren. |
Een eenmalige welkomstbanner kan { once: true } gebruiken. Een functie met meerdere listeners kan die één signaal geven:
const controller = new AbortController();
window.addEventListener("pointermove", moveCursor, {
signal: controller.signal
});
window.addEventListener("keydown", onKey, {
signal: controller.signal
});
// Close the feature:
controller.abort();
Door af te breken verwijder je beide registraties. Een afgebroken controller kan niet worden teruggezet; maak een nieuwe controller voor een nieuwe gebruiksperiode. Geef bij verwijdering met removeEventListener opnieuw capture: true door als dit bij de registratie is gebruikt. once, signal en passive maken geen deel uit van de vergelijking bij het verwijderen.
Een aanroep van preventDefault() door een passieve listener wordt genegeerd. Browsers maken bepaalde listeners die met scrollen te maken hebben op doelen op documentniveau vaak standaard passief, waaronder wheel, touchstart en touchmove; gebruik daar expliciet { passive: false } wanneer annulering nodig is.
Voorkom dat callbacks zich opstapelen
Als elke klik op “Start” een nieuwe anonieme listener aan het bord toevoegt, zorgt twee keer starten ervoor dat één klik op het bord twee callbacks uitvoert. Installeer de bordlistener één keer, gebruik hetzelfde functieobject opnieuw of breek de vorige groep af voordat je die vervangt. Verschillende once-callbacks kunnen zich nog steeds opstapelen voordat ze afgaan.
Als je een element loskoppelt, blijven de listeners behouden. Ze werken als het element opnieuw wordt ingevoegd en dispatchEvent() kan ze bereiken terwijl het is losgekoppeld. Het element komt in aanmerking voor automatische geheugenopruiming wanneer het en de listeners niet meer bereikbaar zijn. Een listener op window of document blijft gekoppeld totdat die expliciet wordt verwijderd.
Verstuur een eigen event
const event = new CustomEvent("cart:add", {
detail: { id: 42 },
bubbles: true
});
item.dispatchEvent(event);
Listeners lezen event.detail.id uit. Bij het versturen worden de listeners onmiddellijk aangeroepen, voordat de aanroep terugkeert. Met bubbles: true kunnen voorouders het event ook ontvangen. Een event dat met dispatchEvent() is verstuurd, heeft isTrusted gelijk aan false; events die door de browser worden verstuurd, kunnen vertrouwd zijn, ook wanneer een API zoals focus() ze heeft veroorzaakt.
Belangrijkste punten
- Bij verwijdering moeten type, functie-identiteit en capture-instelling overeenkomen.
oncebeëindigt één registratie na een aanroep; een signaal afbreken beëindigt de bijbehorende registraties.- Een passieve listener kan een standaardactie niet annuleren.
- Nieuwe callbacks die bij elke installatie worden toegevoegd, kunnen zich opstapelen.
- Als je een element loskoppelt, blijven de listeners behouden.
- Eigen events dragen gegevens in
detailen worden synchroon verstuurd.
2Volg hoe events zich door de pagina verplaatsen
Geneste elementen delen een eventpad. Een klik kan een container passeren voordat die het doel bereikt en de container opnieuw aandoen tijdens de opwaartse propagatie. Daardoor volstaat één listener voor een veranderende lijst. Als je dat pad volgt, begrijp je beter waarom een actie op een kind ook de ouder activeert. Maak onderscheid tussen het annuleren van browsergedrag en het beheersen van eventpropagatie, en gebruik vervolgens de oorsprong van het event om te kiezen welke acties een gedeelde listener moet afhandelen.
2.1 De route van een event door geneste elementen
Een klik binnen een knop kan ook door de voorouders van de knop worden ontvangen. Eventpropagatie is de route van het event door de documentboom. Als je die route volgt, begrijp je zowel nuttige gedeelde listeners als verrassende extra acties.
Volg drie fasen
- Opvang: het event gaat vanaf
windowomlaag via de voorouders naar het doel. - Doel: listeners worden uitgevoerd op het element waar het event begon.
- Opwaartse propagatie: een event dat opwaarts propageert, gaat via de voorouders terug omhoog naar
window.
De eigenschap eventPhase geeft 1 voor opvang, 2 op het doel en 3 voor opwaartse propagatie. Een listener die zonder opties is geregistreerd, wordt uitgevoerd op het doel of op de weg omhoog. Een listener met { capture: true } wordt uitgevoerd op de weg omlaag, ook op het doel als de listener daar is geregistreerd.
Volg een concrete klik
<div id="outer">
<div id="inner">
<button>Go</button>
</div>
</div>
Stel dat de knop en elke div gewone kliklisteners hebben die hun naam naar de console schrijven. Een klik op “Go” schrijft “button”, “inner” en daarna “outer”. Een klik op een leeg deel van inner schrijft “inner” en daarna “outer”; de knop ligt niet op het pad van dat event.
Voeg nu een opvanglistener toe aan outer. Een klik op de knop schrijft eerst “outer (capture)” en daarna “button”, “inner” en “outer” van de gewone listeners. De opvanglistener ziet de klik voordat de nakomelingen dat doen. Na outer kan het event doorgaan via body, html, document en window als daar listeners zijn geregistreerd.
Het is één event, geen nieuwe klik die op elke voorouder wordt gemaakt. target blijft de hele tijd de knop. currentTarget verandert terwijl elke listener wordt uitgevoerd. Ook in de buitenste listener wijst target nog steeds de oorspronkelijke knop aan.
Controleer welke events opwaarts propageren
| Propageert opwaarts | Propageert niet opwaarts |
|---|---|
click, input, change, submit | invalid |
keydown, pointerdown | focus, blur |
focusin, focusout | pointerenter, pointerleave |
pointerover, pointerout | mouseenter, mouseleave |
De eigenschap bubbles van het event vertelt je of het een opwaartse fase heeft. Events zonder opwaartse propagatie kunnen nog steeds door een opvanglistener op een voorouder worden waargenomen. Kies focusin of focusout om focuswijzigingen via een gewone containerlistener af te handelen.
Verklaar een fout bij geneste acties
Een productkaart opent een detailweergave wanneer erop wordt geklikt. De knop “Verwijderen” verwijdert het product. Als je op die knop klikt, wordt eerst het product verwijderd, waarna het event de kaartlistener bereikt en de detailweergave opent. Het eventpad verklaart waarom beide callbacks worden uitgevoerd.
De kaart kan verwijderklikken negeren met if (event.target.closest(".remove")) return;. De knop kan ook de eventpropagatie stoppen. Als je bij de kaart filtert, blijft het event behouden voor andere voorouders die het mogelijk nodig hebben.
Belangrijkste punten
- Bij events die opwaarts propageren volgt de propagatie de opvangfase, de doelfase en daarna de opwaartse fase.
- Gewone listeners op voorouders ontvangen klikken op nakomelingen op de weg omhoog.
targetblijft gelijk terwijlcurrentTargetverandert.- Gebruik een opwaarts propagerend focusevent of de opvangfase om focus vanaf een voorouder waar te nemen.
2.2 Annuleer een actie of stop een event
Een listener kan veranderen wat er na een event gebeurt of waar het event naartoe gaat. Dit zijn afzonderlijke beslissingen. Een event op een link kan opwaarts blijven propageren nadat de navigatie is geannuleerd.
Vervang een browseractie
Een standaardactie is gedrag dat de browser biedt: een link volgen, een formulier verzenden, een selectievakje aan- of uitvinken, tekst invoegen, scrollen met de spatiebalk of de focus verplaatsen met Tab. Gebruik preventDefault() wanneer je code die actie vervangt:
help.addEventListener("click", (event) => {
event.preventDefault();
openHelpPanel();
});
Bij een link naar /help opent dit het paneel zonder te navigeren. De link blijft naar de bestemming verwijzen wanneer JavaScript niet wordt uitgevoerd.
Alleen annuleerbare events ondersteunen annulering. Controleer event.cancelable; defaultPrevented legt vast of de annulering is gelukt. input vindt plaats nadat de waarde verandert en is niet annuleerbaar. Als je daar preventDefault() aanroept, wordt de ingevoegde tekst niet verwijderd. Een annuleerbaar beforeinput-event is de juiste plek om een bewerking te onderscheppen; door een relevant keydown-event te annuleren kun je het standaardeffect van die toets voorkomen.
Beheers de eventpropagatie afzonderlijk
| Methode | Stopt de standaardactie van de browser? | Stopt latere listeners? |
|---|---|---|
preventDefault() | Ja, indien annuleerbaar en niet passief | Nee |
stopPropagation() | Nee | Stopt de doorgang naar andere elementen; listeners op dit element worden nog uitgevoerd |
stopImmediatePropagation() | Nee | Stopt ook de resterende listeners op dit element |
Een link waarvan de listener alleen de eventpropagatie stopt, volgt nog steeds de URL. Als je alleen de navigatie annuleert, kan een kliklistener op het document het event nog steeds ontvangen. false teruggeven vanuit een addEventListener-callback doet geen van beide. Een eigenschap voor een eventhandler of een inline-handler kan de standaardactie annuleren door false terug te geven, maar ook dat stopt de eventpropagatie niet.
Houd gedeeld gedrag werkend
Een voorouder kan een menu sluiten of interacties tellen. Door de eventpropagatie te stoppen verberg je het event voor die code. Vaak kan de voorouder in plaats daarvan target of defaultPrevented controleren.
Een menu sluit bijvoorbeeld alleen wanneer een klik buiten zowel het menu als het openende bedieningselement valt:
document.addEventListener("click", (event) => {
if (!menu.contains(event.target) &&
!menuButton.contains(event.target)) {
menu.hidden = true;
}
});
contains() omvat het element zelf en de nakomelingen ervan. Het openende bedieningselement controleren is belangrijk, omdat de klik die het menu opent ook opwaarts naar het document propageert. Zonder die tweede controle zou het pas geopende menu direct sluiten.
Annuleer alleen een actie die je afhandelt
Controleer in een toetsenlistener de toets voordat je annuleert. Als je elke toets annuleert, blokkeer je gewoon typen en kun je voorkomen dat Tab de focus verplaatst. In een passieve listener wordt annulering helemaal genegeerd.
Belangrijkste punten
preventDefault()annuleert een daarvoor geschikte standaardactie en laat de eventpropagatie doorgaan.stopPropagation()stopt de doorgang van het event, niet de standaardactie.stopImmediatePropagation()slaat ook de resterende listeners op het huidige element over.- Bij
inputis het te laat om een bewerking te annuleren. - Een controle op een klik buiten een pop-up moet zowel de pop-up als het openende bedieningselement omvatten.
- Annuleer alleen de specifieke toetsenbordacties die je code afhandelt.
2.3 Eén listener voor een veranderende lijst
Bij eventdelegatie plaats je een listener op een blijvende voorouder en gebruik je de oorsprong van het event om een actie te kiezen. Dit is nuttig wanneer een lijst veel items heeft of wanneer code na de installatie nieuwe items maakt.
Vind het bedoelde bedieningselement
Een klik die opwaarts propageert, bereikt de lijst ongeacht op welke nakomeling is geklikt. Begin bij event.target, zoek het dichtstbijzijnde overeenkomende bedieningselement en wijs niet-relevante klikken af:
const list = document.querySelector("#todos");
list.addEventListener("click", (event) => {
const button = event.target.closest(".remove");
if (!button || !list.contains(button)) return;
const item = button.closest("li");
console.log("Removing item " + item.dataset.id);
item.remove();
});
De lijst bevat items zoals <li data-id="7">Buy milk <button class="remove">Remove</button></li>. De listener hoort bij de lijst, dus een nieuw item met dezelfde opmaakcode werkt direct na het invoegen.
Volg een klik op een pictogram door de code. Het doel is het pictogram, closest(".remove") vindt de bijbehorende knop en button.closest("li") vindt het item. De data-id van het item identificeert het in de melding. Ten slotte verandert remove() de pagina.
Behoud beide controles
| Controle | Waarom die belangrijk is |
|---|---|
!button | Een klik op een tussenruimte in de lijst of op gewone itemtekst vindt mogelijk geen verwijderknop. |
!list.contains(button) | closest() kan voorbij de lijst omhooggaan en een overeenkomende voorouder daarbuiten vinden. |
Als je alleen event.target.matches(".remove") controleert, mis je klikken op pictogrammen omdat het pictogram zelf niet overeenkomt. closest() controleert het doel en loopt via de voorouders omhoog. In een gedelegeerde listener is currentTarget de lijst; dat wordt niet de gevonden knop.
Stuur meerdere acties aan
Met data-attributen kan één werkbalklistener kiezen uit bekende acties:
const actions = { bold: makeBold, italic: makeItalic,
clear: clearText };
toolbar.addEventListener("click", (event) => {
const button = event.target.closest("button[data-action]");
if (!button || !toolbar.contains(button)) return;
const action = actions[button.dataset.action];
if (typeof action === "function") action();
});
Een knop met data-action="clear" selecteert clearText. De functiecontrole handelt een onbekende actie af zonder te proberen undefined aan te roepen.
Kies een geschikt event
Delegatie werkt ook met andere opwaarts propagerende events dan klikken. Eén input-listener op een formulier kan event.target doorgeven aan een functie die velden controleert. Gebruik focusin of focusout om focuswijzigingen te delegeren; de gewone events focus en blur propageren niet opwaarts. Gebruik voor overgangen bij aanwijzen opwaarts propagerende over- en out-events wanneer delegatie nodig is.
Een stopPropagation() van een nakomeling kan voorkomen dat een event de container bereikt. Als een gedelegeerde listener niet actief lijkt, controleer dan het eventtype, het doel, de overeenkomst met de selector en of iets onder de container de doorgang heeft gestopt.
Belangrijkste punten
- Koppel de listener aan een voorouder die blijft bestaan wanneer de kinderen veranderen.
closest()vindt een bedieningselement ook wanneer op een genest pictogram wordt geklikt.- Wijs ontbrekende overeenkomsten en overeenkomsten buiten de container af.
- Delegatie omvat automatisch overeenkomende kinderen die later worden toegevoegd.
- Data-attributen kunnen een gedeelde listener naar bekende acties leiden.
- Delegatie heeft een event nodig dat de voorouder bereikt.
3Verwerk toetsenbord- en aanwijzerinvoer
Een interactie kan via toetsen, een muis, een vinger of een pen plaatsvinden. Het event dat je kiest, bepaalt of je een activering, een gewijzigde tekstwaarde of de beweging van een specifieke aanwijzer ontvangt. Coördinatenstelsels en opgeslagen beginposities maken slepen voorspelbaar. Focus en alternatieve bedieningselementen houden dezelfde pagina bruikbaar wanneer iemand met het toetsenbord navigeert of geen sleepbeweging kan maken.
3.1 Toetsen, tekst en focus
Toetsenbordinvoer gaat naar het element met focus, beschikbaar als document.activeElement, en propageert daarna opwaarts. Een documentlistener kan daardoor zowel toetsen uit velden als uit andere bedieningselementen ontvangen. Dat bereik maakt sneltoetsen nuttig, maar betekent ook dat ze het typen kunnen onderbreken.
Kies de eigenschap op basis van de betekenis
| Eigenschap | Geeft aan | Voorbeeld |
|---|---|---|
key | De geproduceerde waarde, rekening houdend met indeling en modificatietoetsen | "a", "A", "Enter", " " |
code | De fysieke toetspositie | "KeyA", "Enter", "Space" |
Op een AZERTY-toetsenbord levert de positie met de aanduiding Q op een Amerikaans toetsenbord key "a" en code "KeyQ" op. Gebruik key voor de betekenis, zoals Escape om te sluiten of een letter als sneltoets. Gebruik code voor vaste posities, zoals bewegingstoetsen in een spel. De key van de spatiebalk is één spatie, niet "Space".
keydown gaat af bij de eerste keer indrukken en kan worden herhaald zolang de toets wordt vastgehouden. Herhaalde aanroepen hebben event.repeat === true. keyup gaat af bij het loslaten. Gebruik keydown in plaats van het verouderde event keypress.
Handel een sneltoets nauwkeurig af
document.addEventListener("keydown", (event) => {
if ((event.ctrlKey || event.metaKey) &&
event.key.toLowerCase() === "s") {
event.preventDefault();
saveDraft();
}
});
Dit handelt Ctrl+S en Command+S af. Door de waarde om te zetten naar kleine letters werkt ook "S". De annulering vervangt de browseractie voor het opslaan van de pagina alleen voor de overeenkomende sneltoets. Andere vlaggen voor modificatietoetsen zijn onder meer shiftKey en altKey.
Sla bij een sneltoets met één letter voor de hele pagina invoersituaties over voordat je de actie uitvoert:
if (event.target.matches("input, textarea, select") ||
event.target.isContentEditable) return;
if (event.repeat) return;
De eerste controle beschermt tekstinvoer. De tweede laat een actie één keer per fysieke toetsaanslag uitvoeren. Annuleer Tab niet op de hele pagina; daarmee gaan toetsenbordgebruikers verder.
Luister naar tekst nadat die is gewijzigd
Voor een gewone toets die een zichtbaar teken invoert, is de volgorde keydown, beforeinput, input en daarna keyup. Als je value uitleest bij keydown, krijg je de waarde van vóór het invoegen van dat teken. Gebruik input voor een tekstvoorbeeld of tekenteller. Dit handelt ook bewerkingen af zoals plakken en dicteren, waarvoor geen overeenkomstige toetsaanslag nodig is.
Neem focuswijzigingen waar
focus en blur melden het krijgen en verliezen van focus zonder opwaartse propagatie. focusin en focusout propageren opwaarts, zodat een formulier de velden via één listener kan volgen. relatedTarget geeft het andere betrokken element aan, of null als er geen is.
password.addEventListener("focus", () => {
hint.hidden = false;
});
password.addEventListener("blur", () => {
hint.hidden = true;
});
De aanwijzing is beschikbaar wanneer het veld focus krijgt, ook via Tab. De aanroep element.focus() verplaatst de focus vanuit code; de volgende toetsenbordinvoer gaat dan naar dat element.
Belangrijkste punten
- Gebruik
keyvoor de geproduceerde betekenis encodevoor de fysieke positie. - Bescherm invoersituaties tegen lettersneltoetsen voor de hele pagina en voorkom ongewenste herhalingen.
- Gebruik
inputom te reageren op tekstbewerkingen, waaronder plakken. focusinenfocusoutpropageren opwaarts;focusenblurdoen dat niet.relatedTargetgeeft de andere bestemming of oorsprong van de focus aan.
3.2 Activering en beweging van de aanwijzer
Iemand kan een muis, vinger, pen of toetsenbord gebruiken. Kies een event op basis van de interactie die je nodig hebt. click staat voor activering; pointerevents beschrijven indrukken, bewegen en loslaten.
Houd acties beschikbaar via het toetsenbord
Een ingebouwde knop laat click afgaan wanneer die met Enter of de spatiebalk wordt geactiveerd. Een link met focus doet dat bij Enter. Als je een actie alleen aan pointerdown of mousedown koppelt, mis je die activeringen via het toetsenbord. Gebruik click voor acties zoals het openen van een paneel; gebruik pointerdown wanneer de actie bij het indrukken moet beginnen, zoals bij slepen.
Een klik met een aanwijzer volgt op indrukken en loslaten. Wanneer die op verschillende elementen plaatsvinden, kan de klik hun dichtstbijzijnde gemeenschappelijke voorouder als doel hebben. dblclick volgt op twee snelle klikken; event.detail telt snelle opeenvolgende klikken. auxclick handelt klikken met een niet-primaire knop af. contextmenu kan voortkomen uit een klik met de secundaire knop, lang indrukken op een touchscreen of een menuopdracht via het toetsenbord.
Gebruik één familie van pointerevents
pointerdown, pointermove, pointerup en pointercancel werken voor muis, aanraking en pen. pointerType geeft het apparaat aan als "mouse", "touch" of "pen"; pointerId onderscheidt actieve aanwijzers, waaronder twee vingers.
Oudere families van muis- en aanrakingsevents bestaan nog steeds. Browsers kunnen na pointerevents muisevents voor compatibiliteit laten afgaan. Als je zowel pointerdown als mousedown voor dezelfde actie registreert, kan die daardoor twee keer worden uitgevoerd.
Kies coördinaten die bij de taak passen
| Coördinaten | Oorsprong |
|---|---|
clientX, clientY | Linkerbovenhoek van de zichtbare viewport |
pageX, pageY | Linkerbovenhoek van het document, inclusief scrollen |
offsetX, offsetY | Buitenrand van de padding van het doelelement |
Wanneer het document 300 px omlaag is gescrold en een klik 100 px onder de bovenkant van de viewport valt, is clientY gelijk aan 100 en pageY aan 400. Houd beide posities in hetzelfde coördinatenstelsel wanneer je een beweging berekent. Een veranderend genest doel kan ook de oorsprong van offsetcoördinaten veranderen.
button geeft aan welke knop bij een down- of up-event van toestand veranderde: 0 primair, 1 midden, 2 secundair. buttons geeft de combinatie aan die momenteel wordt ingedrukt: primair draagt 1 bij, secundair 2 en midden 4. Dus buttons === 3 betekent dat primair en secundair zijn ingedrukt; het betekent niet dat de middelste knop van toestand veranderde.
Kies gedrag bij aanwijzen voor een heel bedieningselement
Over- en out-events propageren opwaarts en kunnen afgaan wanneer de aanwijzer grenzen van kindelementen passeert. Enter- en leave-events propageren niet opwaarts en beschrijven het binnenkomen of verlaten van het hele element, inclusief de kinderen. Met pointerenter en pointerleave kan een tooltip flikkeren bij kindgrenzen voorkomen.
Gebruikers van touchscreens en toetsenborden gebruiken geen aanwijzen zonder aanraking. Bied essentiële informatie ook aan bij een klik of focus. Voor een visueel effect bij aanwijzen zonder extra gedrag is CSS :hover eenvoudiger dan een listener.
Belangrijkste punten
- Gebruik
clickvoor activering, inclusief ingebouwde activering met het toetsenbord. - Pointerevents ondersteunen muis, aanraking en pen met één eventfamilie.
- Kies voor berekeningen coördinaten uit hetzelfde stelsel.
buttongeeft een verandering aan;buttonsgeeft de ingedrukte combinatie aan.- Enter- en leave-events behandelen een element en de kinderen ervan als één geheel.
- Essentiële informatie moet ook zonder aanwijzen toegankelijk zijn.
3.3 Een sleepactie die de aanwijzer blijft volgen
Voor slepen moet je gegevens over meerdere events heen onthouden. Sla de begincoördinaten van de aanwijzer en de beginpositie van het element op. Elke beweging past dan het verschil met dat beginpunt toe, zodat het element niet verspringt om de hoek onder de aanwijzer te plaatsen.
Bereken de verplaatsing
Een vak begint op left: 100px; top: 50px. De aanwijzer begint op viewportcoördinaten 220, 140 en beweegt naar 260, 125. De horizontale verandering is 40 px; de verticale verandering is −15 px. Als je die veranderingen bij de beginpositie van het vak optelt, krijg je left: 140px; top: 35px.
Gebruik voor beide metingen van de aanwijzer dezelfde clientcoördinaten. De algemene berekening is de beginpositie van het element plus de verplaatsing van de aanwijzer. Tel niet telkens de volledige verplaatsing op bij de al bijgewerkte positie van het vak, want dan tel je eerdere beweging opnieuw mee.
Onthoud en leg één aanwijzer vast
Voor een absoluut gepositioneerd vak zonder marge binnen een relatief gepositioneerde container:
let start = null;
box.addEventListener("pointerdown", (event) => {
if (start || event.button !== 0) return;
start = { id: event.pointerId, x: event.clientX,
y: event.clientY, left: box.offsetLeft,
top: box.offsetTop };
box.setPointerCapture(event.pointerId);
});
box.addEventListener("pointermove", (event) => {
if (!start || event.pointerId !== start.id) return;
box.style.left = start.left +
(event.clientX - start.x) + "px";
box.style.top = start.top +
(event.clientY - start.y) + "px";
});
function endDrag(event) {
if (start && event.pointerId === start.id) start = null;
}
box.addEventListener("pointerup", endDrag);
box.addEventListener("pointercancel", endDrag);
Het opgeslagen ID wijst beweging en loslaten van een tweede aanwijzer af. offsetLeft en offsetTop geven beginposities als getallen; stijlen hebben het achtervoegsel "px" nodig.
Door de aanwijzer vast te leggen blijven volgende events voor die aanwijzer naar het vak gaan, ook wanneer de aanwijzer buiten het vak beweegt. De browser beëindigt de vastlegging nadat de aanwijzer is losgelaten of de actie is geannuleerd. releasePointerCapture(id) kan die eerder beëindigen.
Handel af dat de browser de controle overneemt
Een aanraakgebaar kan scrollen of zoomen van de pagina worden en zo pointercancel veroorzaken. Beëindig de sleepactie daar net als bij pointerup; anders kan achtergebleven toestand het vak later blijven bewegen. Pas vóór de interactie touch-action: none toe op het sleepgebied om het gebaar daarvoor te reserveren. Beperk dit tot dat gebied, zodat de rest van de pagina kan scrollen.
Gebruik user-select: none op het versleepbare oppervlak om tekstselectie te voorkomen. Stel draggable="false" in op de afbeeldingen ervan om het ingebouwde sleepgedrag voor afbeeldingen te voorkomen.
Bied een andere manier van verplaatsen
Bied toetsenbordbediening voor een bedieningselement met focus en verplaatsknoppen waarop je kunt klikken of tikken. Pijltjestoetsen alleen bieden geen alternatief met één aanwijzer voor slepen. WCAG 2.2-succescriterium 2.5.7 vereist zo'n alternatief, tenzij slepen essentieel is of het ongewijzigd browsergedrag betreft. Ingebouwde verplaatsknoppen kunnen zowel toetsenbordgebruikers als aanwijzergebruikers bedienen.
De afzonderlijke HTML Drag and Drop API gebruikt dragstart, dragover en drop om gegevens, zoals bestanden, over te dragen. De eventvolgorde verschilt van deze positiewijziging met een aanwijzer.
Belangrijkste punten
- Bereken elke positie vanuit de opgeslagen beginpositie plus de verplaatsing van de aanwijzer.
- Leg de aanwijzer vast en volg het ID van de actieve aanwijzer.
- Beëindig de sleepactie bij zowel
pointerupalspointercancel. - Pas regels voor aanraking en selectie toe op het sleepgebied.
- Bied toetsenbordtoegang en een alternatief waarop je kunt klikken of tikken.
4Verwerk formulieren en valideer invoer vóór verzending
Formulieren combineren verschillende soorten toestand: tekst, numerieke waarden, aangevinkte keuzes en herhaalde namen. Lees die waarden uit bij het juiste event en handel vervolgens de verzending van het formulier af als één actie. HTML-invoerregels bieden veelgebruikte validatieregels, terwijl JavaScript relaties tussen velden en duidelijkere feedback toevoegt. Een bruikbaar formulier bewaart het werk van de gebruiker, legt elke correctie uit en plaatst de focus waar de volgende bewerking hoort.
4.1 Lees waarden uit wanneer ze veranderen
Formulierbedieningselementen bieden toegang tot verschillende soorten toestand. De value van een tekstveld is een string; de checked van een selectievakje is een booleaanse waarde. De juiste eigenschap uitlezen is de eerste stap naar betrouwbare berekeningen en voorbeelden.
Converteer getallen bewust
Zelfs <input type="number"> heeft een string als value. Bij de tekst "3" geeft het optellen van 1 de waarde "31". Number(input.value) + 1 geeft 4. Een getalveld biedt ook valueAsNumber.
Lege invoer vraagt om een aparte beslissing. Number("") geeft 0, waardoor een ontbrekende hoeveelheid op een echte nul kan lijken. Controleer eerst input.value === "", of gebruik valueAsNumber, dat NaN geeft voor een leeg getalveld. Controleer dat resultaat met Number.isNaN().
Lees de geselecteerde toestand uit
| Bedieningselement | Eigenschap om uit te lezen |
|---|---|
| Tekstveld, tekstgebied, keuzelijst | value |
| Getalveld gebruikt bij berekeningen | valueAsNumber, of een niet-lege value converteren |
| Selectievakje | checked voor de aan- of uitstatus |
Groep keuzerondjes met de naam size | form.elements.size.value voor de geselecteerde waarde |
De value van een selectievakje is de ingestelde tekst voor verzending, of "on" als er geen is opgegeven. Die waarde vertelt je niet of het vakje is aangevinkt. Een keuzelijst geeft de waarde van de gekozen optie. Om het geselecteerde keuzerondje zelf te vinden, zoek je met input[name="size"]:checked.
Stem het event af op de bijwerking
input meldt bewerkingen door de gebruiker terwijl ze plaatsvinden, waaronder typen en plakken. change meldt een bevestigde keuze: nadat een gewijzigd tekstveld focus verliest, of direct wanneer een selectievakje, keuzerondje of keuzelijst wordt gewijzigd.
message.addEventListener("input", () => {
counter.textContent = 280 - message.value.length +
" characters left";
});
Na “Hello” zijn vijf tekens gebruikt en toont de teller “275 characters left”. Een keydown-listener zou worden uitgevoerd voordat het nieuwe teken in de waarde komt en zou plakken via een menu missen. Als je message.value vanuit code toewijst, gaat input noch change af; roep de functie voor het bijwerken dan ook rechtstreeks aan.
Verzamel de benoemde velden van een formulier
form.elements.email.value geeft toegang tot een bedieningselement via de naam of het ID. Gebruik form.elements["first-name"] voor een naam met een koppelteken. Verzending gebruikt namen: een ID alleen zorgt er niet voor dat een veld in de gegevens wordt opgenomen.
const data = new FormData(form);
const email = data.get("email");
const topics = data.getAll("topics");
FormData verzamelt de huidige naam-waardeparen die daarvoor in aanmerking komen. Niet-aangevinkte selectievakjes, uitgeschakelde bedieningselementen en velden zonder naam worden weggelaten. get() geeft de eerste waarde voor een naam terug; getAll() bewaart herhaalde waarden, zoals meerdere aangevinkte onderwerpen. Bestandsvelden kunnen bestandsobjecten opleveren; gewone tekstvelden leveren strings.
Object.fromEntries(data) is handig voor afzonderlijke namen, maar bewaart bij herhaalde namen alleen het laatste paar. Kies getAll() wanneer elke selectie van belang is. Omdat input opwaarts propageert, kan één formulierlistener event.target uitlezen om het gewijzigde veld bij te werken.
Belangrijkste punten
- Converteer de string van een veld vóór het rekenen en handel een leeg getalveld afzonderlijk af.
- Lees de toestand van een selectievakje uit via
checked. - Gebruik
inputvoor directe bewerkingen enchangevoor bevestigde keuzes. FormDatabevat benoemde bedieningselementen die daarvoor in aanmerking komen, niet elk bedieningselement.getAll()bewaart herhaalde namen; conversie naar een object doet dat niet.- Een waarde toewijzen vanuit code laat geen bewerkingsevents afgaan.
4.2 Handel de verzending van het formulier af
Verzending hoort bij het formulier. Luister naar het submit-event om een klik op een verzendknop, Enter in een veld met één regel en een requestSubmit() vanuit een script via één route af te handelen.
Vervang navigatie door een paginabijwerking
Normaal verstuurt een formulier gegevens naar de URL in action en laadt het antwoord. Zonder action is de bestemming de huidige pagina. De standaardmethode GET plaatst de gegevens in de URL. Om de huidige pagina met JavaScript bij te werken, annuleer je die standaardactie:
const form = document.querySelector("#new-todo");
form.addEventListener("submit", (event) => {
event.preventDefault();
const data = new FormData(form);
const title = data.get("title").trim();
if (title === "") return;
addTodo(title);
form.reset();
});
Dit formulier heeft een ingeschakeld tekstveld met de naam title. De listener verwijdert spaties aan de uiteinden, negeert een leeg resultaat, voegt een item toe en zet velden terug op hun beginwaarden. reset() betekent niet altijd leegmaken; een bedieningselement met een beginwaarde krijgt die waarde weer terug.
Als het item even verschijnt en verdwijnt wanneer de pagina opnieuw wordt geladen, controleer dan of preventDefault() ontbreekt. Alleen een kliklistener op een knop is niet de juiste plek om een formulier af te handelen, vooral niet wanneer het formulier ook via een andere route wordt verzonden.
Weet wat verzending in gang zet
Impliciete verzending met Enter kan op de ingeschakelde standaardverzendknop klikken. Enter in een tekstgebied voegt een nieuwe regel in. Een knop binnen een formulier is standaard een verzendknop als het type wordt weggelaten, dus een knop “Wachtwoord tonen” moet expliciet type="button" gebruiken.
Bij meerdere verzendknoppen geeft event.submitter aan welke is gebruikt. De waarde kan null zijn bij routes zonder specifieke knop, dus code moet dit controleren voordat die de waarde uitleest:
const button = event.submitter;
const intent = button ? button.value : "save";
const data = button ? new FormData(form, button) :
new FormData(form);
Een benoemde verzendknop zoals name="intent" value="publish" draagt dat paar bij wanneer die aan FormData wordt doorgegeven. Een aanroep van alleen FormData(form) bevat het naam-waardepaar van een verzendknop niet.
Behoud de validatieroute
| Verzendroute | Automatische validatie | submit-listener |
|---|---|---|
Activering van een verzendknop of requestSubmit() | Wordt uitgevoerd tenzij validatieattributen die overslaan | Wordt uitgevoerd als validatie dat toestaat |
form.submit() | Wordt overgeslagen | Wordt overgeslagen |
Ingebouwde validatie wordt uitgevoerd vóór het submit-event. Als een leeg verplicht veld niet aan de regels voldoet, meldt de browser het probleem en verstuurt die submit niet. Een eigen controle die alleen binnen die listener staat, wordt bij deze mislukte poging niet uitgevoerd. novalidate op het formulier schakelt de automatische validatiestap uit.
Gebruik requestSubmit() wanneer code de normale route via validatie en het submit-event nodig heeft. De methode vraagt verzending aan zonder een klik op een knop te versturen. Geef een specifieke verzendknop door aan requestSubmit(button) wanneer de verzendinstellingen van die knop moeten gelden.
Belangrijkste punten
- Handel
submitaf op het formulier, voor verzending door gebruikers en vanuit scripts. - Annuleer de standaardverzending wanneer JavaScript de navigatie vervangt.
- Geef formulierknoppen die niet verzenden
type="button". - Gebruik
submitterom verzendknoppen te onderscheiden en neem zo nodig de gegevens ervan op. - Validatie gaat vooraf aan
submit;requestSubmit()behoudt die route. submit()slaat validatie en het submit-event over.reset()herstelt de beginwaarden.
4.3 Laat HTML validatieregels beschrijven
HTML kan veel invoerregels beschrijven zonder een eigen JavaScript-controle. De browser controleert die regels tijdens verzending en stelt de resultaten beschikbaar aan je code. Begin met de invoerregels die passen bij de gegevens die je nodig hebt.
Kies een invoerregel
| Attribuut | Regel |
|---|---|
required | Een waarde of verplichte selectie moet worden opgegeven. |
type="email" of "url" | De waarde moet de verwachte syntaxis hebben. |
min, max, step | Getal- of datumwaarden moeten binnen grenzen en stapgroottes passen. |
minlength, maxlength | Door de gebruiker ingevoerde tekst moet aan een lengteregel voldoen. |
pattern | Een niet-lege tekstwaarde moet overeenkomen met een expressie voor de hele waarde. |
Bij pattern="[0-9]{5}" wordt “12345” goedgekeurd; “1234”, “123456” en “12345a” worden afgekeurd. Het patroon omvat de hele waarde, niet een willekeurig overeenkomend deel ervan. Lege invoer slaat de patrooncontrole over, dus voeg required toe wanneer weglaten niet is toegestaan.
E-mailvalidatie controleert de syntaxis, niet of een inbox bestaat. Zowel “ann@example.com” als “ann@example” voldoet aan de e-mailregel van de browser, terwijl “ann.example.com” daar niet aan voldoet. Een aanvullend patroon kan een specifiekere vorm vereisen wanneer de applicatie dat nodig heeft.
Lees de reden van afkeuring uit
Het validity-object van een veld bevat booleaanse vlaggen. valueMissing, typeMismatch, patternMismatch, tooShort en tooLong beschrijven ontbrekende of onjuist gevormde tekst. rangeUnderflow, rangeOverflow en stepMismatch beschrijven numerieke invoerregels. badInput betreft invoer die de browser niet kan omzetten in een bruikbare waarde, en customError legt een eigen geldigheidsmelding vast. valid is waar wanneer aan alle invoerregels is voldaan.
Bij een getalveld met min="0" max="10" step="2" ligt 12 boven het maximum, past 7 niet bij de toegestane stapgrootte en wordt 6 goedgekeurd. Meer dan één vlag kan waar zijn; ga er niet van uit dat elk ongeldig veld precies één probleem heeft.
Controleer zonder melding of meld zichtbaar
checkValidity() geeft een booleaanse waarde terug en laat invalid afgaan op ongeldige bedieningselementen zonder de browsermelding te tonen. reportValidity() controleert en meldt het probleem ook aan de gebruiker. Roep een van beide aan op een veld of formulier. validationMessage geeft de melding in de taal van de browser. Het invalid-event propageert niet opwaarts.
Regels voor tekstlengte gelden voor tekst die de gebruiker invoert. Door input.value = "ab" toe te wijzen in code wordt tooShort niet waar alleen omdat minlength gelijk is aan 3. maxlength voorkomt normaal ook dat de gebruiker voorbij de grens verder typt.
Toon fouten op een behulpzaam moment
:invalid is direct van toepassing, dus een onaangeraakt verplicht veld voldoet er al aan. :user-invalid wacht op interactie van de gebruiker of een verzendpoging en kan een vroeg rood veld voorkomen. Gebruik naast een visuele stijl ook tekst om de fout uit te leggen.
novalidate slaat automatische validatie bij verzending voor het formulier over; formnovalidate slaat die over voor één verzendknop. Ze verwijderen geen invoerregels en schakelen checkValidity() niet uit. Browsercontroles helpen gebruikers fouten te herstellen; de server moet ontvangen gegevens opnieuw valideren omdat een verzoek buiten de pagina om kan gaan.
Belangrijkste punten
- Gebruik HTML-invoerregels voor verplichte waarden, syntaxis, bereiken, stapgroottes, lengte en patronen.
- Een patroon komt overeen met de hele niet-lege waarde; gebruik
requiredom lege invoer af te wijzen. - Lees
validity-vlaggen uit om te bepalen waarom een veld is afgekeurd. checkValidity()controleert;reportValidity()toont ook feedback.- Attributen die validatie overslaan, laten de validatie-API bruikbaar.
- Valideer ontvangen gegevens ook op de server.
4.4 Eigen regels en bruikbare foutmeldingen
Een regel waarbij twee velden betrokken zijn, heeft code nodig. Een bevestiging moet bijvoorbeeld overeenkomen met een wachtwoord, of een einddatum moet na een begindatum komen. Houd de regel gescheiden van hoe en wanneer de fout ervan wordt weergegeven.
Stel een eigen fout in en wis die
Een niet-lege string die aan setCustomValidity() wordt doorgegeven, markeert het veld als ongeldig en stelt customError in. Door "" door te geven wis je die eigen fout; het veld kan nog steeds niet voldoen aan required, pattern of andere invoerregels.
function checkMatch() {
const matches = confirm.value === password.value;
confirm.setCustomValidity(matches ? "" :
"The passwords do not match.");
}
password.addEventListener("input", checkMatch);
confirm.addEventListener("input", checkMatch);
Controleer beide afhankelijkheden opnieuw. Als het eerste wachtwoord verandert, kan een eerder correcte bevestiging niet meer overeenkomen. Een melding die nooit wordt gewist, houdt het veld ongeldig nadat de gebruiker het verschil heeft hersteld. Voer ook de eerste controle uit wanneer velden met waarden kunnen beginnen.
Datumvelden leveren ISO-strings zoals "2026-03-10", ongeacht de weergegeven lokale datumnotatie. Niet-lege waarden uit deze velden kun je als tekst vergelijken. Als de regel zegt dat het einde na het begin moet komen, wijs dan end.value <= start.value af, inclusief gelijkheid. Handel ontbrekende datums af met required of een aparte controle op een lege waarde.
Leg de volgende nuttige actie uit
Een melding moet het probleem en de correctie benoemen. Zeg bij een ontbrekend e-mailadres: “Vul je e-mailadres in.” Zeg bij onjuist gevormde e-mailtekst: “Vul een e-mailadres in de vorm naam@example.com in.” Behoud de ingevoerde waarde zodat de gebruiker die kan bewerken.
Een verplicht naamveld accepteert spaties omdat ze een niet-lege string vormen. Controleer name.value.trim() === "" wanneer witruimte aan de uiteinden niet moet meetellen. Wis deze eigen fout wanneer betekenisvolle tekst verschijnt.
Koppel meldingen aan bedieningselementen
<label for="email">Email</label>
<input id="email" name="email" type="email"
required aria-describedby="email-error">
<p id="email-error"></p>
Plaats de foutmelding in die paragraaf en stel aria-invalid="true" in zolang het veld een fout heeft. Wis de tekst en verwijder aria-invalid of zet die op "false" na correctie. aria-describedby koppelt de uitleg voor hulptechnologie aan het veld. Gebruik tekst; een rode rand alleen kan niet iedereen vertellen wat er mis is.
Kies de validatiestroom
Voeg voor volledig eigen meldingen novalidate toe en gebruik een submit-listener op het formulier. Werk eigen regels bij, controleer de geldigheid van de velden, schrijf hun meldingen en voorkom verzending als een veld ongeldig is. Verplaats de focus naar het eerste ongeldige veld of naar een gekoppeld foutenoverzicht. Als JavaScript ook een succesvolle verzending lokaal afhandelt, annuleer dan ook die standaardverzending.
Meld onvolledige e-mailtekst niet bij elke eerste toetsaanslag. Een bruikbare volgorde is fouten tonen na focusverlies of verzending en een al gemelde fout daarna opnieuw controleren bij input.
Belangrijkste punten
- Niet-lege eigen meldingen maken een veld ongeldig;
""wist alleen die eigen fout. - Controleer elk veld opnieuw waarvan een regel tussen velden afhankelijk is.
- Wijs voor een strikte datumvolgorde zowel gelijkheid als een eerder einde af.
- Leg een correctie uit in tekst en koppel die aan het veld.
- Wis zichtbare fouten en de ARIA-foutstatus na correctie.
- Eigen feedback bij verzending heeft een expliciete stroom voor geldigheid en focus nodig.
5Bouw eigen bedieningselementen die iedereen kan gebruiken
Door een ingebouwd element te kiezen krijg je veel gedrag van een bedieningselement voordat je een listener schrijft. Eigen bedieningselementen vragen dezelfde zorg: een duidelijke naam, toegang met het toetsenbord, zichtbare focus en een status die overeenkomt met wat hulptechnologie meldt. Groepen hebben voorspelbare verplaatsing tussen items nodig. Wanneer inhoud opent, sluit of verdwijnt, kan de gebruiker met een bewust gekozen focusbestemming de interactie voortzetten zonder opnieuw de pagina te doorzoeken.
5.1 Begin met een ingebouwd bedieningselement
Een bedieningselement heeft meer nodig dan een reactie op een klik. Mensen moeten het kunnen vinden, bereiken en bedienen, het doel ervan begrijpen en zien waar de focus is. Ingebouwde HTML biedt veel van dit gedrag al.
Kies het element dat bij de taak past
Gebruik een <button> voor een actie, een <a href> voor navigatie en een formulierbedieningselement met een label voor invoer. <details> met <summary> biedt een uitklapcomponent. Geef deze elementen met CSS een stijl die bij de pagina past. Een knop met focus wordt met Enter of de spatiebalk geactiveerd zonder extra toetsenlistener.
Een div met een kliklistener heeft geen van de ingebouwde betekenis of het toetsenbordgedrag van de knop. Als je die role="button" geeft, verandert wat hulptechnologie meldt, maar wordt de div niet focusbaar en worden toetsaanslagen niet omgezet in klikken.
| Behoefte | Ingebouwde knop | Eigen div die als knop werkt |
|---|---|---|
| Rol | Ingebouwd | Voeg role="button" toe. |
| Toetsenbordfocus | Ingebouwd | Voeg tabindex="0" toe. |
| Enter en spatiebalk | Ingebouwd | Voeg toetsenbordbediening toe. |
| Toegankelijke naam | Meestal de eigen tekst | Geef betekenisvolle tekst of een ARIA-naam. |
| Uitgeschakeld gedrag | disabled | Controleer aria-disabled in code. |
Houd de focusvolgorde voorspelbaar
tabindex="0" voegt een element toe aan de normale tabvolgorde volgens de documentvolgorde. tabindex="-1" staat focus vanuit code toe zonder een tabstop toe te voegen. Positieve waarden plaatsen elementen vóór de gebruikelijke volgorde en zijn moeilijk te onderhouden; vermijd ze.
Geen van beide instellingen voegt activeringsgedrag toe. Een focusbare eigen knop heeft nog steeds een listener nodig voor toetsenbordbediening. Een rol, een tabstop en een callback lossen verschillende delen van de interactie op.
Geef elk bedieningselement een naam
Een schermlezer gebruikt een toegankelijke naam om bedieningselementen te onderscheiden. Een tekstknop kan de zichtbare tekst gebruiken. Een tekstveld of keuzelijst heeft een gekoppeld label nodig, zoals <label for="email">Email</label> in combinatie met id="email". aria-labelledby kan verwijzen naar zichtbare tekst elders; aria-label kan een naam bieden wanneer er geen geschikte zichtbare tekst is.
Een sluitknop met alleen een pictogram kan <button type="button" aria-label="Close">×</button> zijn. De naam beschrijft de actie zodat de gebruiker niet hoeft af te leiden wat het symbool betekent.
Toon en handhaaf de status
Houd een focusindicator zichtbaar. Als je de standaardrand vervangt, zorg dan voor een duidelijke vervanging met :focus-visible, bijvoorbeeld outline: 3px solid #1a73e8. Als je de rand zonder vervanging verwijdert, verberg je de positie van de toetsenbordgebruiker.
Een uitgeschakelde ingebouwde knop verdwijnt uit de tabvolgorde en kan niet op de gewone manier worden geactiveerd. aria-disabled="true" geeft alleen aan dat het element niet beschikbaar is. De klik- en toetsenbordactie van een eigen bedieningselement moeten die status controleren en terugkeren zonder een actie uit te voeren. Door die controle in de activeringsfunctie onder te brengen, blijven beide invoerroutes consistent.
Belangrijkste punten
- Gebruik een ingebouwd element dat past bij de actie of invoer.
- Een ARIA-rol biedt betekenis, geen gedrag.
- Gebruik
tabindex="0"voor normale toegang met Tab en-1voor focus uitsluitend vanuit code. - Zorg voor een toegankelijke naam en een zichtbare focusindicator.
- Handhaaf
aria-disabledin de activeringscode.
5.2 Houd toetsenbordgedrag en status bij elkaar
Een eigen bedieningselement moet hetzelfde resultaat geven, ongeacht hoe het wordt geactiveerd. Zet de actie in één functie, leid toetsenbord- en aanwijzerinvoer daarheen en werk de status bij die zowel voor de vormgeving als door hulptechnologie wordt uitgelezen.
Geef een eigen knop toetsenbordactivering
fakeButton.addEventListener("click", activate);
fakeButton.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
activate();
}
});
Dit is bedoeld voor een eigen focusbare knop. Door de spatiebalk te annuleren voorkom je dat de pagina tijdens de actie scrollt. Een ingebouwde knop produceert al klikken bij activering met het toetsenbord, dus als je daar een tweede toetsenbordroute aan toevoegt, kan de actie twee keer worden uitgevoerd.
Kies de status die bij het bedieningselement past
| Bedieningselement | Status |
|---|---|
| Schakelknop met een vast label | aria-pressed="true" of "false" |
| Knop die een uitklapcomponent opent | aria-expanded="true" of "false" |
| Eigen selectievakje of schakelaar | aria-checked="true" of "false" |
Een schakelknop “Dempen” behoudt dat label en verandert aria-pressed. Als het ontwerp het actielabel verandert in “Geluid aanzetten”, laat je aria-pressed weg. Een selectievakje gebruikt role="checkbox" en de spatiebalk om te schakelen; een schakelaar gebruikt role="switch" voor de aan- of uitstatus.
Attributen bevatten strings. Vergelijk getAttribute("aria-expanded") met "true", niet met de booleaanse waarde true:
detailsButton.addEventListener("click", () => {
const open = detailsButton.getAttribute(
"aria-expanded") === "true";
detailsButton.setAttribute("aria-expanded", String(!open));
panel.hidden = open;
});
Als open waar was, is de nieuwe status onwaar en wordt het paneel verborgen. aria-controls kan het paneel via een ID aangeven. De ingebouwde elementen <details> en <summary> bieden uitklapgedrag zonder dit script.
Gebruik het statusattribuut als bron voor de vormgeving, zoals [aria-pressed="true"], zodat de zichtbare en gemelde status tegelijk veranderen. Sluit pop-ups bij Escape en geef de focus terug aan het openende bedieningselement.
Geef een groep één tabstop
Bij tabbladen, werkbalken en groepen keuzerondjes gebruik je Tab om de groep in of uit te gaan en de pijltjestoetsen om binnen de groep te bewegen. Een verschuivend tabstoppunt houdt het huidige item op 0 en de andere items op -1. Zet bij een verplaatsing het oude item op -1, het nieuwe item op 0 en geef het nieuwe item focus.
Bij drie items ga je vanaf index 2 naar rechts met (2 + 1) % 3 terug naar 0. Naar links vanaf 0 gebruik je (0 - 1 + 3) % 3 om 2 te bereiken. Tel de lengte op vóór de restbewerking, omdat -1 % 3 in JavaScript gelijk is aan −1.
Controleer met het toetsenbord: ga naar het bedieningselement, zie de focus, activeer het met de juiste toetsen, beweeg binnen een groep en sluit een pop-up met Escape. Controleer bij elke wijziging de zichtbare status en de ARIA-status.
Belangrijkste punten
- Leid klikken, Enter en de spatiebalk bij een eigen knop naar één actie.
- Ingebouwde knoppen bieden al klikactivering via het toetsenbord.
- Kies
aria-pressed,aria-expandedofaria-checkedvoor de bijbehorende status. - Vergelijk ARIA-waarden als strings en werk de vormgeving bij vanuit dezelfde status.
- Een verschuivend tabstoppunt geeft een groep één tabstop en laat je met pijltjestoetsen bewegen.
- Escape sluit een pop-up en geeft de focus terug aan het openende bedieningselement.
5.3 Verplaats de focus wanneer de pagina verandert
De focus bepaalt waar de volgende toetsenbordactie terechtkomt. Als het bedieningselement met focus verdwijnt, kan de gebruiker de plaats kwijtraken. Behandel focus als onderdeel van de paginabijwerking, vooral bij het openen van een dialoogvenster, het verwijderen van een item of het melden van een fout.
Open een dialoogvenster en keer terug naar het openende element
Onthoud het element met focus voordat je opent. Verplaats de focus naar de nieuwe interactie en herstel die bij het sluiten:
let opener;
openButton.addEventListener("click", () => {
opener = document.activeElement;
dialog.showModal();
});
dialog.addEventListener("close", () => {
if (opener && opener.isConnected) opener.focus();
});
showModal() op een ingebouwd dialoogvenster verplaatst de focus naar binnen en maakt de rest van de pagina inactief, zodat je daar niet op kunt klikken of focus naartoe kunt verplaatsen zolang het modale venster open is. Escape veroorzaakt normaal een cancel-event, gevolgd door sluiting en een close-event. Een cancel-listener kan het sluiten voorkomen als de applicatie dat gedrag nodig heeft.
Kies een nuttige beginpositie voor de focus in het dialoogvenster, zoals het eerste relevante bedieningselement. Bij een eigen pop-up moet code de focus bewust verplaatsen. Als het oorspronkelijke openende element niet meer bestaat, kies dan een nuttig bedieningselement in de buurt in plaats van een losgekoppeld element focus te proberen geven.
Maak een nuttige bestemming focusbaar
Een kop of foutenoverzicht is normaal niet focusbaar. Geef het tabindex="-1" voordat je .focus() aanroept. Het kan dan bij een bewuste verplaatsing focus krijgen zonder een extra stop te worden tijdens de normale navigatie met Tab. Gebruik 0 alleen wanneer het element in die normale volgorde thuishoort.
Behoud de positie na verwijdering
Zoek voordat je een lijstitem verwijdert waarvan de verwijderknop focus heeft, de volgende nuttige bestemming. Geef de knop van het volgende item focus; gebruik de knop van het vorige item als er geen volgend item is. Als de lijst leeg wordt, geef je de kop ervan focus met tabindex="-1".
Door de bestemming vóór verwijdering te zoeken, voorkom je dat de relatie met naburige items verloren gaat. Stuur de focus niet na elke verwijdering naar de bovenkant van het document; de gebruiker moet verder kunnen werken in de buurt van de wijziging.
Houd de focus binnen een doorlopende interactie
Een pop-up kan sluiten wanneer de focus het hele gebied ervan verlaat. Het opwaarts propagerende focusout-event geeft de bestemming:
menu.addEventListener("focusout", (event) => {
if (!menu.contains(event.relatedTarget)) {
menu.hidden = true;
}
});
Als de focus tussen twee menubedieningselementen beweegt, sluit het menu niet omdat de bestemming binnen het menu blijft. Een bestemming null ligt ook buiten het menu; contains(null) is onwaar. Geef de focus niet automatisch terug aan het openende element wanneer de gebruiker bewust naar een ander bedieningselement op de pagina is gegaan.
Maak wijzigingen voorspelbaar
Geef na mislukte eigen formuliervalidatie het eerste ongeldige veld of een foutenoverzicht dat naar de fouten linkt focus. Ingebouwde validatie geeft een ongeldig veld al focus. Houd de fouttekst beschikbaar zodat de gebruiker weet wat te corrigeren.
Spring niet naar een nieuw veld terwijl de gebruiker typt en navigeer niet zodra een keuzelijst verandert. Laat de gebruiker de wijziging met een duidelijke actie bevestigen. Een focusverplaatsing moet een bewuste actie of herstel ondersteunen, niet gewone invoer onderbreken.
Belangrijkste punten
- Onthoud het openende element en herstel de focus naar een beschikbare bestemming wanneer een dialoogvenster sluit.
- Gebruik
tabindex="-1"voor een kop of overzicht dat vanuit code focus krijgt. - Geef na verwijdering een naburig item of de kop van de lege lijst focus.
- Gebruik
relatedTargetom focusverplaatsingen binnen een pop-up te onderscheiden van het verlaten ervan. - Geef na mislukte validatie een foutbestemming focus; vermijd onverwachte focussprongen.
JavaScript-events: voorbeelden
1Bouw en onderzoek eventlisteners
13 stappen
- 1IntroductieLaat een knop reageren
Een listener koppelt een event aan een functie. Bouw een kleine teller door de knop te kiezen, de actie ervan te registreren en het totaal tussen aanroepen te bewaren. Onderzoek daarna een
clickin geneste elementen en bepaal hoelang de listener actief blijft.Let op het verschil tussen installatiecode, die nu wordt uitgevoerd, en de callback, die de browser aanroept wanneer het gekozen event plaatsvindt.
- 2VoorbeeldSla het totaal buiten de callback op
Selecteer de bestaande knop en sla de tellerwaarde op vóór de registratie:
const button = document.querySelector("#like"); let likes = 0; button.addEventListener("click", () => { likes = likes + 1; button.textContent = "Likes: " + likes; });Elke aanroep telt op bij het vorige totaal. Na drie klikken is het label “Likes: 3”. Een teller die binnen de callback is gedeclareerd, zou bij elke aanroep opnieuw beginnen.
- 3TipGeef de actie door zonder die aan te roepen
addEventListener("click", showMenu)geeft een functie door voor later gebruik.showMenu()zou die tijdens de installatie aanroepen. Gebruik() => showMenu("main")wanneer argumenten nodig zijn.Laad het script nadat de knop bestaat, bijvoorbeeld met
defer, en behoud de exacte spelling van het event. Een listener voor"Click"ontvangt geen gewone"click"-events. - 4UitdagingHerstel een registratie
Een knop moet bij elke activering het tips-paneel openen. De installatie gebruikt momenteel
button.addEventListener("click", openTips()). Wat moet veranderen en waarom?---reveal---
Geef
openTipsdoor zonder haakjes. Daarmee geef je de callback door die bij een latereclickmoet worden uitgevoerd. Als jeopenTips()tijdens de installatie aanroept, opent het paneel direct en geef je het resultaat door in plaats van de actie te bewaren voor het event. - 5UitlegLees de twee elementeigenschappen uit
Bij een knop die een afbeelding bevat, maakt een klik op de afbeelding die afbeelding tot
target. In de listener van de knop iscurrentTargetde knop.De
targetgeeft aan waar het event begon; de huidigetarget, oftewel het element van de actieve listener, geeft aan waar deze callback is geregistreerd. Dat verschil verklaart waarom het uitlezen van dedatasetvan een knop viatargetkan mislukken wanneer declickop de afbeelding ervan terechtkomt. - 6VoorbeeldLees de gegevens van de bijbehorende knop uit
Stel dat
buttoneendata-id="7"heeft en een pictogram bevat:button.addEventListener("click", (event) => { console.log(event.currentTarget.dataset.id); });Het resultaat is
"7"voor zowel eenclickop het pictogram als eenclickop de achtergrond van de knop. Dezelfde expressie werkt in een listener met een pijlfunctie of een gewone functie. Dethisvan een pijlfunctie verwijst niet automatisch naar de knop. - 7UitdagingBepaal bij welk element de listener hoort
Een sectie bevat een knop met een span. Alleen aan de sectie is een
click-listener gekoppeld en op de span wordt geklikt. Welke elementen geventargetencurrentTargetaan tijdens die callback?---reveal---
targetgeeft de span aan waar het event begon.currentTargetgeeft de sectie aan waar de listener is gekoppeld. De oorsprong van het event wordt niet vervangen door de voorouder die het ontvangt. - 8UitlegBewaar de referentie voor verwijdering
Voor verwijdering zijn hetzelfde eventtype, callbackobject en dezelfde capture-instelling nodig:
const handler = () => closePanel(); button.addEventListener("click", handler); button.removeEventListener("click", handler);Een anonieme functie kan worden verwijderd als je die op deze manier bewaart. Een nieuwe
() => closePanel()schrijven in de verwijderaanroep maakt een ander object dat niet overeenkomt met de eerdere registratie. - 9VerbandBeëindig meerdere registraties tegelijk
Een tijdelijke functie kan één signaal van een
AbortControlleraan meerdere registraties doorgeven. De aanroepcontroller.abort()verwijdert die listeners, inclusief opgeslagen of anonieme callbacks.Gebruik een nieuwe controller voor een volgende gebruiksperiode. Voor één eenmalige reactie verwijdert
{ once: true }die registratie nadat die is uitgevoerd. Geen van beide opties voorkomt dat verschillende callbacks zich opstapelen voordat hun levensduur eindigt. - 10UitdagingOnderzoek herhaalde installatie
Telkens wanneer een paneel wordt geopend, registreert de code een nieuwe anonieme toetsenlistener op het document. Sluiten verbergt het paneel maar laat de listener staan. Na drie keer openen veroorzaakt één toets drie acties. Hoe kun je de levenscyclus herstellen?
---reveal---
Verwijder de registraties wanneer het paneel sluit, bijvoorbeeld door hun gedeelde signaal af te breken, en maak een nieuwe controller bij het opnieuw openen. Je kunt ook een callback bewaren en dezelfde referentie verwijderen. Het paneel verbergen verwijdert geen documentlistener.
- 11KernpuntVerstuur direct een melding
Maak een
CustomEventmet de gegevens indetailom andere code te informeren. Stelbubbles: truein als voorouders het event moeten ontvangen:item.dispatchEvent(new CustomEvent("cart:add", { detail: { id: 42 }, bubbles: true }));De listeners worden uitgevoerd voordat de aanroep terugkeert. Bij het verstuurde event is
isTrustedonwaar. Het is een melding die je code verstuurt, geen verzoek aan de browser om op een gebruikersactie te wachten. - 12UitdagingCombineer oorsprong en levensduur
De
click-handler van een knop gebruikt de eigendata-keyen mag alleen bij de eerste activering handelen. De knop bevat een SVG-pictogram. Welke eigenschap en optie zorgen dat aan beide eisen wordt voldaan?---reveal---
Lees
event.currentTarget.dataset.keyuit in de directe listener van de knop en registreer met{ once: true }. De eigenschap geeft de bijbehorende knop aan, ook bij eenclickop het pictogram. De optie verwijdert die registratie na de eerste aanroep. - 13SamenvattingControleer een listener op drie plaatsen
Als een interactie mislukt, onderzoek dan de installatie, de gegevens van de callback en de levensduur ervan. Controleer of het element bestaat en de eventnaam exact is; bekijk
targetencurrentTargettijdens de aanroep; zoek daarna naar ontbrekende verwijdering of herhaalde registratie. Met deze controles onderscheid je een listener die nooit een event ontvangt van een listener die het correct ontvangt maar op het verkeerde element handelt.
2Volg events en delegeer acties
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieVolg één klik door een kaart
- 2VoorbeeldLees de weg omhoog
- 3UitlegVoeg de weg omlaag toe
- 4UitdagingVolg een kleinere boom
- 5UitlegVervang navigatie
- 6KernpuntDe doorgang stoppen is een andere keuze
- 7UitdagingHoud een observerende listener op de ouder actief
- 8UitlegVerplaats de listener naar de lijst
- 9VoorbeeldZoek en controleer de verwijderknop
- 10UitdagingHandel een genest pictogram af
- 11TipGebruik een event dat de container bereikt
- 12UitdagingHoud openen en sluiten gescheiden
- 13SamenvattingKies voor elke actie waar je die afhandelt
3Verwerk toetsen en bouw een sleepactie met een aanwijzer
16 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieKies het juiste invoerniveau
- 2UitlegOnderscheid betekenis van positie
- 3TipBescherm het typen en handel herhalingen af
- 4UitdagingKies een event voor een voorbeeldweergave
- 5VerbandLaat activering ook met het toetsenbord werken
- 6VoorbeeldZet om naar een ander coördinatenstelsel
- 7UitdagingOnderzoek een klik na scrollen
- 8KernpuntMaak aanwijzen niet tot de enige route
- 9VoorbeeldBereken één sleepbeweging
- 10UitlegSla het begin op en leg de aanwijzer vast
- 11VoorbeeldPas de verplaatsing bij elke beweging toe
- 12TipBeëindig ook als de browser het overneemt
- 13UitdagingVoorspel een doorgaande sleepactie
- 14VerbandBied verplaatsing zonder slepen aan
- 15UitdagingOnderzoek twee fouten bij slepen
- 16SamenvattingStem het event af op de taak
4Bouw een volledige formulierinteractie
16 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieVolg een formulier van bewerken tot verzenden
- 2VoorbeeldLees een getal uit zonder concatenatie
- 3UitlegLees keuzes en herhaalde namen uit
- 4UitdagingBehoud elk geselecteerd onderwerp
- 5UitlegHandel verzending af op het formulier
- 6VoorbeeldLees uit, voeg toe en herstel
- 7UitdagingBehoud de normale verzendroute
- 8VoorbeeldLees afzonderlijke fouten in invoerregels uit
- 9KernpuntEen patroon vereist geen waarde
- 10UitdagingControleer een bereik met stapgrootte
- 11UitlegVoeg een regel toe die twee velden verbindt
- 12TipOnderscheid geldigheid van het moment van foutmelding
- 13UitdagingHerstel een niet-bijgewerkte datumregel
- 14VerbandNeem verantwoordelijkheid als je browserfeedback overslaat
- 15UitdagingMaak de herstelstroom af
- 16SamenvattingControleer zowel geldige als ongeldige routes
5Bouw bedieningselementen en behoud de toetsenbordpositie
14 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieLaat een interactie via het toetsenbord werken
- 2UitlegGebruik gedrag dat HTML al biedt
- 3TipStel focusbaarheid in voor de bedoelde route
- 4UitdagingHerstel een onbereikbare actie
- 5VoorbeeldGebruik één activeringsfunctie
- 6UitlegDruk de juiste soort status uit
- 7UitdagingKeer een uitklapcomponent correct om
- 8VoorbeeldVerplaats één tabstop binnen een groep
- 9VerbandOnthoud waar een dialoogvenster vandaan kwam
- 10VoorbeeldHoud een interne focusverplaatsing binnen de pop-up
- 11UitdagingKies de focus na verwijdering
- 12UitdagingVolg een groepsbijwerking
- 13UitdagingHoud een pop-up voorspelbaar
- 14SamenvattingTest de volledige reeks voor het bedieningselement
JavaScript-events: oefenvragen
Set 1: Stel eventlisteners in en onderzoek ze10 Oefenvragen
Vraag 1 van 10
showHints alleen aanroepen wanneer die wordt geactiveerd. Welke registratie zorgt daarvoor?Toon antwoordVerberg antwoord
click plaatsvindt. Met showHints() roep je de functie tijdens de registratie aan en geef je de retourwaarde door. Een omhullende functie als () => showHints geeft alleen de functie terug; die voert de bedoelde actie nooit uit.Vraag 2 van 10
addEventListener. Door welke laadwijziging wacht de selectie totdat de HTML is ontleed?Toon antwoordVerberg antwoord
defer wordt geladen, wordt na het ontleden van het document uitgevoerd, zodat de knop bestaat wanneer die wordt geselecteerd. De oorspronkelijke selectie gaf null terug omdat de opmaakcode nog niet was ontleed. Een directe functieaanroep vanuit hetzelfde vroege script verandert dat moment niet.Vraag 3 van 10
const items = document.querySelectorAll(".choice"); items.addEventListener("click", choose);. Alle keuzes bestaan al. Waarom mislukt dit en hoe moet de installatie veranderen?Toon antwoordVerberg antwoord
addEventListener heeft. Doorloop de elementen en registreer choose op elk element, of delegeer vanaf een geschikte voorouder. Een aanroep van choose() maakt de collectie niet tot een eventdoel en roept de functie bovendien te vroeg aan.Vraag 4 van 10
button.onclick = first; button.onclick = second;. Wat gebeurt er als één keer op de knop wordt geklikt?Toon antwoordVerberg antwoord
onclick bewaart één callback, dus de tweede toewijzing vervangt de eerste. Bij de klik wordt vanuit die eigenschap alleen second uitgevoerd. Als je twee verschillende functies met addEventListener registreert, kunnen ze allebei naast elkaar bestaan, maar deze instructies wijzen één eigenschap voor een eventhandler toe.Vraag 5 van 10
target en currentTarget tijdens die listener?Toon antwoordVerberg antwoord
target van het event geeft die span aan. De listener is aan de knop gekoppeld, waardoor de knop tijdens de aanroep currentTarget is. De locatie van de listener vervangt de oorsprong van het event niet wanneer op een genest element wordt geklikt.Vraag 6 van 10
<button data-code="r8"><span>Run</span></button> leest event.target.dataset.code uit. Waarom kan dat undefined teruggeven en met welke expressie leest de directe listener de code van de knop uit?Toon antwoordVerberg antwoord
data-code. currentTarget geeft de knop aan waaraan deze listener is gekoppeld, dus de dataset ervan bevat de code. Een pijlfunctie krijgt de knop niet als this, dus overstappen op this.dataset lost het probleem niet betrouwbaar op.Vraag 7 van 10
currentTarget: null. Hoe kan de ontwikkelaar tijdens de aanroep bekijken bij welk element de listener hoort?Toon antwoordVerberg antwoord
currentTarget in voor elke listeneraanroep en zet die daarna terug. Schrijf de eigenschap rechtstreeks binnen de callback naar de console om tijdens die aanroep het bijbehorende element te zien. Als je het eventobject later bekijkt, kun je de teruggezette toestand zien; target is de oorsprong en kan een ander element zijn.Vraag 8 van 10
{ capture: true }. Hetzelfde type en dezelfde functie worden aan removeEventListener doorgegeven, maar er wordt geen derde argument opgegeven. Waarom blijft de callback bestaan?Toon antwoordVerberg antwoord
true of { capture: true } door; je hoeft once, passive of signal niet te herhalen om die listener aan te wijzen.Vraag 9 van 10
board.addEventListener("click", () => mark()). Na twee keer beginnen maakt één klik op het bord twee markeringen. Welke wijziging in de installatie voorkomt die opstapeling?Toon antwoordVerberg antwoord
once aan twee verschillende callbacks toevoegt, wachten er nog steeds twee callbacks op de volgende klik, zodat beide een markering kunnen maken voordat ze zichzelf verwijderen.Vraag 10 van 10
Een knop zonder andere listeners krijgt deze registraties en wordt daarna twee keer aangeklikt. Hoe vaak wordt log in totaal uitgevoerd?
button.addEventListener("click", log, { once: true });
button.addEventListener("click", log);
button.addEventListener("click", log, true);
button.removeEventListener("click", log);
Toon antwoordVerberg antwoord
Set 2: Volg geneste acties en eventdelegatie10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
focus-listener, maar die wordt niet aangeroepen wanneer een invoerveld daarbinnen focus krijgt. Hoe kan het formulier focus op nakomelingen waarnemen zonder de opvangfase te gebruiken?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
event.stopPropagation() aan. Wat gebeurt er met de normale navigatie?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
preventDefault() aan. Op een omringende sectie bestaat ook een gewone submit-listener. Wat kan de listener van de sectie waarnemen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
closest(".action") binnen een container die in een buitenste .action-element ligt. Een klik op een tussenruimte vindt dat buitenste element. Welke controle houdt de afhandeling binnen de container?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
closest(".remove") en controles op de container. Nieuwe knoppen werken, behalve in één rij waarvan de pictogramlistener stopPropagation() aanroept. De padding van de knop in dezelfde rij werkt wel. Waarom ontstaat dit verschil?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Verwerk toetsenbord-, aanwijzer- en sleepinvoer10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
keydown. Welke wijziging verhelpt beide problemen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
pointerdown. Welk event moet de actie afhandelen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
clientY 75. Wat is de verticale coördinaat ten opzichte van het document?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
pointerout. Welk event herkent het verlaten van de hele kaart beter?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
left: 65px; top: 90px. De aanwijzer begint op 180, 210 en beweegt naar 155, 245 in clientcoördinaten. Welke positie moet het vak bereiken?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Lees formuliergegevens uit en onderzoek validatie10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
"6". Wat levert input.value + 2 op?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
topic en de waarden "art" en "code" in documentvolgorde, een niet-aangevinkt topic met de waarde "music" en een uitgeschakeld notitieveld met een naam. Wat geeft new FormData(form).getAll("topic") terug en waarom is conversie naar een object riskant?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
form.submit() aan en de formulierlistener die navigatie voorkomt, wordt nooit uitgevoerd. Welke aanroep herstelt de verwachte stroom en wat gebeurt er voordat dat veld is gecorrigeerd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
pattern="[A-Z]{3}" en is optioneel. Voldoet een lege waarde aan deze patroonregel?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
min="2" max="14" step="4". De gebruiker voert 12 in. Aan welke regel wordt niet voldaan?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
novalidate en controleert velden bij verzending in documentvolgorde. Het veld voor de hoeveelheid is verplicht en heeft min="2" max="14" step="4"; het bevat nu 10 en een oude eigen melding is gewist met setCustomValidity(""). Het volgende veld is een verplicht e-mailadres dat leeg is. Welk veld moet deze poging blokkeren en focus krijgen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
end.value < start.value af en wordt alleen uitgevoerd bij bewerkingen van de einddatum. Welke twee wijzigingen herstellen de resterende fouten tussen de velden?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 5: Bouw toetsenbordtoegang en behoud de focus10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
role="button" en een kliklistener. Wat biedt de rol zelf?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
activate(). De knop heeft aria-disabled="true". De functie begint met if (button.getAttribute("aria-disabled") === true) return;, maar beide routes voeren nog steeds de actie uit. Welke correctie handhaaft de uitgeschakelde status en staat tegelijk toe dat de status met de string “false” werkt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
aria-expanded="true" en een zichtbaar paneel. De klikhandler leest de oude uitgeklapte status uit. Wat moet de volgende status zijn?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
tabindex="-1". De verwijderknop met focus in het laatste item verwijdert dat item; later wordt ook het resterende item verwijderd. Welke focusvolgorde ondersteunt verder gebruik met het toetsenbord?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
Aanwijzer vastleggen
AbortController
abort() wordt aangeroepen.Activering
click bij gebruik van een aanwijzer of ingebouwde toetsenbordbediening.click, of die nu met de spatiebalk of met een muis wordt ingedrukt.Alternatief met één aanwijzer zonder slepen
aria-describedby
aria-describedby koppelt een bedieningselement aan beschrijvende tekst door de ID's op te sommen van de elementen die die tekst bevatten.email-error zodat hulptechnologie de fout aan het veld kan koppelen.aria-invalid
aria-invalid geeft aan dat de ingevoerde waarde van een bedieningselement een fout bevat; code moet het attribuut bijwerken wanneer de fout verandert.aria-invalid="true" zolang de correctiemelding ernaast wordt getoond.ARIA-rol
role="button" heeft nog steeds code voor activering en een geschikte tabstop nodig.ARIA-status
aria-checked van de schakelaar wordt bijgewerkt wanneer de zichtbare aan- of uitstatus verandert.B
Bitmasker voor aanwijzerknoppen
buttons van het event.buttons 3, een combinatie van de vlaggen 1 en 2.C
cancelable
cancelable is een booleaanse waarde die aangeeft of een event toestaat dat de standaardactie ervan via preventDefault() wordt geannuleerd.input-event meldt een bewerking die al is uitgevoerd, dus de eigenschap cancelable ervan is onwaar.change-event
change-event meldt een bevestigde wijziging door de gebruiker, zoals het verlaten van een bewerkt tekstveld of het kiezen van een nieuwe status van een selectievakje of keuzelijst.change afgaan wanneer de gebruiker het verlaat voor het volgende bedieningselement.checked
checked is de booleaanse status die aangeeft of een selectievakje of keuzerondje is geselecteerd, onafhankelijk van de waarde voor verzending.checkbox.checked uit om te bepalen of een optioneel gedeelte wordt getoond.checkValidity
checkValidity() geeft terug of aan de invoerregels is voldaan en laat bij fouten invalid-events afgaan zonder browserfeedback te tonen.closest
closest() controleert een element en daarna de voorouders ervan op de dichtstbijzijnde overeenkomst met een selector en geeft null terug als die niet bestaat.closest("button") de omringende actieknop.code
code geeft een fysieke toetspositie aan, onafhankelijk van het teken dat de huidige toetsenbordindeling produceert.code wanneer de bewegingstoetsen op vaste fysieke posities moeten blijven.contains
contains() controleert of een knooppunt het element zelf of een van de nakomelingen ervan is en geeft een booleaanse waarde terug.list.contains(button) voordat die de actie van de knop toestaat.Controle op een klik buiten het element
currentTarget
currentTarget geeft het object aan waarvan de listener wordt uitgevoerd en wordt teruggezet op null nadat de eventafhandeling is geëindigd.currentTarget de gegevens van die knop uitlezen.CustomEvent
detail kan bevatten en zo kan worden ingesteld dat het opwaarts naar voorouders propageert."cart:add" met de identificatie van het item in de detail van het event.D
Data-attribuut
data- en applicatiegegevens opslaat die via de dataset van een element beschikbaar zijn.data-action="clear" uit als button.dataset.action om een bekende actie te selecteren.defaultPrevented
defaultPrevented is een booleaanse waarde die vastlegt of de standaardactie van een event met succes is geannuleerd.defaultPrevented controleren voordat die beslist hoe een klik wordt afgehandeld.Documentcoördinaten
pageX en pageY worden gemeten vanaf de linkerbovenhoek van het document, inclusief scrollen.pageY 400.Doelfase
eventPhase 2 terwijl ze worden aangeroepen.E
Eigenschap voor een eventhandler
onclick die één eventcallback bevat en die vervangt wanneer je opnieuw een waarde toewijst.button.onclick toewijst, vervangt die de eerdere handler van die eigenschap.Event
click-event laat de pagina reageren wanneer iemand de knop voor de volgende afbeelding in een galerij activeert.Eventdelegatie
Eventlistener
Eventobject
key van het ontvangen event om te bepalen of een paneel moet sluiten.Eventpropagatie
F
Focus
document.activeElement.search.focus() stuurt het volgende getypte teken naar het zoekveld.Focusbeheer
Focusindicator
:focus-visible-rand toont welke werkbalkknop de volgende toetsactie ontvangt.FormData
data.getAll("topics") alle geselecteerde waarden samen op.Formulierherstel naar de beginwaarden
form.reset() de velden terug op hun beginwaarden.Foutenoverzicht
Functiereferentie
openPanel door te geven registreer je de functie; door openPanel() door te geven roep je de functie tijdens de installatie aan.G
Gebruikte verzendknop
event.submitter wanneer een specifieke knop die route in gang heeft gezet.I
Inactieve achtergrond
Ingebouwd HTML-bedieningselement
input-event
input-event meldt een bewerking door de gebruiker nadat de waarde van een bedieningselement verandert, inclusief tekstbewerkingen zonder fysieke toetsaanslag.input-listener van het veld een teller bij.K
key
key geeft de waarde die een toets produceert, rekening houdend met de toetsenbordindeling en modificatietoetsen zoals Shift.key-waarde van een letter veranderen van "a" in "A", terwijl de positie gelijk blijft.keydown
keydown-event meldt een toetsaanslag vóór het normale bewerkingseffect en kan worden herhaald zolang de fysieke toets ingedrukt blijft.keydown op Escape voordat het open paneel sluit.L
Listeneridentiteit
M
Modaal dialoogvenster
showModal() opent het ingebouwde dialoogvenster en verplaatst de focus naar de inhoud.N
novalidate
novalidate slaat automatische validatie op basis van invoerregels tijdens verzending over, terwijl de regels en geldigheidsmethoden beschikbaar blijven.novalidate zodat de submit-listener elk veld zelf kan controleren.O
once
once vraagt om automatische verwijdering van die registratie na de eerste aanroep voor het geselecteerde eventtype.once: true gebruiken voor de klik die de banner tijdens deze gebruiksperiode sluit.Openend bedieningselement
Opvangfase
Opwaartse eventpropagatie
bubbles waar is.input-event van een kindveld propageert opwaarts naar een listener die op het omringende formulier is geregistreerd.P
Passieve eventlistener
preventDefault() in een passieve aanraaklistener stopt het scrollen van de browser niet.pattern
pattern definieert voor ondersteunde tekstvelden een regel met een reguliere expressie die op de hele waarde wordt toegepast, uitsluitend wanneer die waarde niet leeg is.required nodig om een leeg veld af te wijzen.pointercancel
pointercancel-event meldt dat de browser de aanwijzerinteractie heeft geannuleerd, waardoor een sleepactie de actieve toestand moet wissen.pointercancel.Pointerevent
pointermove-listener kan beweging van een muis of een aanraking uitlezen.pointerId
pointerId geeft een afzonderlijke aanwijzer aan tijdens een interactie, zodat gelijktijdige aanrakingen apart kunnen worden afgehandeld.preventDefault
preventDefault() annuleert in een niet-passieve listener de standaardactie van een daarvoor geschikt event zonder de eventpropagatie te stoppen.preventDefault() aan voordat die zonder navigatie een lokaal item toevoegt.R
relatedTarget
relatedTarget geeft het andere element aan dat bij een focusovergang betrokken is, of is null wanneer zo'n element niet beschikbaar is.focusout-listener van een menu controleert of de bestemming binnen het menu blijft.reportValidity
reportValidity() controleert invoerregels en vraagt de browser ook om validatiefeedback te tonen voor niet-afgehandelde fouten.reportValidity() aan om de gebruiker te helpen een ongeldig veld te vinden.requestSubmit
requestSubmit() vraagt formulierverzending aan via de normale route met validatie en het submit-event, zonder een klik op een knop te laten afgaan.form.requestSubmit() aan zodat de validatie en submit-listener van het formulier nog steeds worden uitgevoerd.S
Samengestelde groep bedieningselementen
Schakelknop
aria-pressed om de huidige status te melden.aria-pressed wisselt tussen waar en onwaar.Sleeptoestand
Standaardactie
stopImmediatePropagation
stopImmediatePropagation() stopt de doorgang van een event en slaat ook de resterende listeners over die op het huidige eventdoel zijn geregistreerd.stopPropagation
stopPropagation() voorkomt dat een event doorgaat naar verdere elementen, terwijl andere listeners op het huidige element actief blijven.submit-event
submit-event is een annuleerbaar formulierevent dat tijdens de normale verzendroute wordt verstuurd nadat automatische validatie verzending toestaat.submit-listener van een formulier handelt een geldige verzending af door lokaal een item toe te voegen en navigatie te annuleren.Synchrone eventafhandeling
dispatchEvent() worden uitgevoerd, voordat die methode de controle teruggeeft aan de aanroepende code.dispatchEvent() naar de console wordt geschreven, verschijnt na meldingen van de listeners.T
tabindex
tabindex bepaalt deelname aan de gewone tabvolgorde en focusbaarheid vanuit code, waarbij 0 in de normale volgorde staat en −1 daarbuiten.tabindex="-1" zodat code die focus kan geven zonder een gewone tabstop toe te voegen.target
target geeft de oorsprong van het event aan. Dat kan een genest element zijn binnen het bedieningselement waarvan de actie wordt afgehandeld.target van de klik.Toegankelijke naam
aria-label="Close" om aan te geven wat het symbool doet.touch-action
touch-action geeft aan welke aanraakgebaren van de browser zijn toegestaan wanneer een gebaar op een element begint.touch-action: none op het sleepgebied te gebruiken, reserveer je de beweging in dat gebied voor de sleepactie.U
Uitklapcomponent
aria-expanded.V
Validatie op basis van HTML-invoerregels
ValidityState
validity van een bedieningselement beschikbaar is en booleaanse vlaggen bevat die aangeven aan welke invoerregels niet is voldaan.stepMismatch melden hoewel die tussen het minimum en maximum ligt.value
value maakt de huidige waarde van een formulierbedieningselement als tekst beschikbaar, ook bij getalvelden waarvan de numerieke inhoud nog moet worden geconverteerd."8" moet worden geconverteerd voordat code er een getal bij optelt.valueAsNumber
valueAsNumber leest de numerieke waarde van een ondersteund invoerveld rechtstreeks uit en geeft NaN terug wanneer geen bruikbare numerieke waarde aanwezig is.NaN op, wat code herkent met Number.isNaN().Verschuivend tabstoppunt
Viewportcoördinaten
clientX en clientY worden gemeten vanaf de linkerbovenhoek van het zichtbare gebied.Vlag voor een modificatietoets
ctrlKey of metaKey samen met de letter S.W
Witruimte aan het begin en einde verwijderen
name.value.trim() === "" herkent een naam die geheel uit spaties bestaat.Z
Zelf ingestelde geldigheid
setCustomValidity() wordt ingesteld, waarbij een niet-lege melding het bedieningselement ongeldig maakt.Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.