Ga naar hoofdinhoud

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
En álle matches dan?

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 het zelf.

Editor laden...

Investigate

Experimenteer in het veld hierboven:

  • Vervang toggle door add. Wat gebeurt er als je twee keer klikt?
  • Verander querySelector('.kaart') in querySelector('h2'). Waar komt de markering nu terecht, en waarom ziet dat er anders uit?
  • Voeg in de HTML een tweede .kaart toe. Welke van de twee reageert op de knop?

Opdracht 1: Reset-knop

Voeg een tweede knop toe die de klasse actief verwijdert (alleen verwijderen, niet togglen).

Editor laden...
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.

Editor laden...
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.

Editor laden...
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.