Modern DOM
Je kent getElementById voor elementen met een id. Deze les geeft je twee nieuwe gereedschappen: één zoekfunctie die met elke CSS-selector werkt, en een nette manier om stijlen aan en uit te zetten via klassen.
querySelector: zoeken met een CSS-selector
document.querySelector(...) geeft het eerste element dat aan een CSS-selector voldoet — dezelfde selectors die je uit CSS kent:
document.querySelector('#welkom'); // element met id="welkom"
document.querySelector('.kaart'); // eerste element met class="kaart"
document.querySelector('button'); // eerste <button> op de pagina
document.querySelector('.kaart h2'); // h2 binnen .kaart
Daarvoor bestaat querySelectorAll, die een lijst teruggeeft. Om daar iets mee te doen heb je loops nodig — die komen zo.
classList: klassen aan- en uitzetten
In plaats van losse .style-regels vanuit JavaScript definieer je de stijl in CSS, en schakel je met JavaScript een klasse:
const kaart = document.querySelector('.kaart');
kaart.classList.add('actief'); // voeg klasse toe
kaart.classList.remove('actief'); // verwijder klasse
kaart.classList.toggle('actief'); // aan als hij uit is, uit als hij aan is
kaart.classList.contains('actief'); // true of false
In CSS staan dan twee toestanden:
.kaart {
background-color: lightgray;
}
.kaart.actief {
background-color: gold;
border: 3px solid orange;
}
Toggle de klasse en de CSS doet de rest. Zo blijft de vormgeving in het CSS-bestand, ook als er meerdere eigenschappen tegelijk veranderen.
Predict
Wat denk je dat dit doet?
document.querySelector('p').textContent = 'Veranderd.';
Met deze HTML:
<p>Eerste</p>
<p>Tweede</p>
<p>Derde</p>
Welke paragrafen veranderen er?
Alleen de eerste <p> krijgt de tekst "Veranderd." — querySelector stopt bij de eerste match. De andere twee blijven staan.
Probeer en onderzoek
- Vervang
classList.toggledoorclassList.adden klik twee keer. Wat gebeurt er?Antwoord
Na de eerste klik is de kaart goud met een oranje rand, en na de tweede klik blijft hij dat.addzet de klasse aan, maar uitzetten doet alleentoggleofremove. - Verander
querySelector('.kaart')inquerySelector('h2')en klik. Wat zie je, en waarom?Antwoord
Er verandert niets. De<h2>krijgt de klasseactiefwel, maar de CSS-regel.kaart.actiefgeldt alleen voor een element met allebei de klassen, en de<h2>heeft geen klassekaart. - Kopieer in de HTML het hele blok
<div class="kaart">tot en met</div>en zet de kopie eronder. Welke van de twee kaarten reageert op de knop?Antwoord
Alleen de bovenste.querySelectorgeeft het eerste element dat bij de selector past; de tweede kaart blijft grijs.
Opdracht 1: Reset-knop
Voeg een tweede knop toe die de klasse actief verwijdert (alleen verwijderen, niet togglen).
Tip
Een aparte functie met classList.remove('actief'), gekoppeld aan een eigen knop met een eigen id.
Antwoord
HTML:
<button id="resetKnop">Reset</button>
script.js:
function reset() {
document.querySelector('.kaart').classList.remove('actief');
}
document.getElementById('resetKnop').addEventListener('click', reset);
Opdracht 2: Nachtmodus
Maak een knop "Nachtmodus" die een klasse donker op de <body> toggelt. Schrijf zelf de CSS: donkere achtergrond, lichte tekst.
Tip
Ook 'body' is een geldige selector. De CSS-klasse schrijf je als body.donker { ... }.
Antwoord
HTML:
<button id="nachtKnop">Nachtmodus</button>
CSS-toevoeging:
body.donker {
background-color: #222;
color: white;
}
script.js:
function nachtmodus() {
document.querySelector('body').classList.toggle('donker');
}
document.getElementById('nachtKnop').addEventListener('click', nachtmodus);
Eén toggle, en alles wat in de klasse staat schakelt tegelijk mee — dat is de winst ten opzichte van losse .style-regels.
Opdracht 3: Takenkaartje
Bouw een takenkaartje af. De kaart staat al klaar, met twee knoppen: "Klaar" toggelt de klasse klaar (groene achtergrond, doorgestreepte tekst) en "Belangrijk" toggelt de klasse belangrijk (rode rand). Schrijf de CSS voor beide klassen en de twee functies.
Tip
Schrijf twee functies en koppel ze met addEventListener aan de knoppen (klaarKnop en belangrijkKnop). Doorstrepen doe je in CSS met text-decoration: line-through;. De twee klassen mogen tegelijk aan staan.
Antwoord
CSS-toevoeging:
.kaart.klaar {
background-color: lightgreen;
text-decoration: line-through;
}
.kaart.belangrijk {
border: 3px solid red;
}
script.js:
function markeerKlaar() {
document.querySelector('.kaart').classList.toggle('klaar');
}
function markeerBelangrijk() {
document.querySelector('.kaart').classList.toggle('belangrijk');
}
document.getElementById('klaarKnop').addEventListener('click', markeerKlaar);
document.getElementById('belangrijkKnop').addEventListener('click', markeerBelangrijk);
Er gaat iets mis
querySelector geeft null als er niets gevonden wordt
const kaart = document.querySelector('.bestaat-niet');
kaart.classList.add('actief');
Uncaught TypeError: Cannot read properties of null (reading 'classList')
Geen match betekent null, en op null bestaat geen classList. Controleer bij twijfel eerst of het element gevonden is:
const kaart = document.querySelector('.bestaat-niet');
if (kaart !== null) {
kaart.classList.add('actief');
}
Hetzelfde geldt voor getElementById: ook die geeft null bij een onbekend id.