Gå til innhold

Hendelser

Events er ting som skjer på nettsiden. Tenk på det som signaler - noe skjer, og JavaScript fanger det opp.

Hva betyr «event»?

Mange begreper i JavaScript er engelske ord som gir mening når du oversetter dem. Event betyr rett og slett hendelse - noe som skjer. En event listener er noe som lytter etter hendelser. Hvis du husker dette, blir koden mye lettere å forstå.

Eksempler på events:

  • En bruker klikker på en knapp
  • En bruker skriver i et tekstfelt
  • En bruker beveger musen over et bilde
  • En bruker trykker en tast på tastaturet
  • Et skjema sendes inn
  • Siden er ferdig lastet

Med JavaScript kan du lytte etter disse signalene og reagere på dem. Det er dette som gjør nettsider interaktive!

Hvordan det fungerer

For å reagere på en hendelse trenger du tre ting:

  1. Elementet - hva skal vi lytte på? (Se DOM for å velge elementer)
  2. Hendelsen - hvilken hendelse skal vi lytte etter?
  3. Funksjonen - hva skal skje når hendelsen inntreffer?
let knapp = document.querySelector("button");  // 1. Elementet

knapp.addEventListener("click", function() {   // 2. Hendelsen ("click")
    alert("Du klikket!");                       // 3. Funksjonen (vis popup)
});

Slik ser flyten ut:

Bruker klikker på knappen
        ↓
JavaScript oppdager "click"-hendelsen
        ↓
Funksjonen kjøres → alert("Du klikket!")

Lytte etter hendelser

addEventListener er metoden vi bruker for å koble en hendelse til et element. Tenk på det som å si: "Hei element, gi meg beskjed når dette skjer!"

element.addEventListener("hendelse", function() {
    // kode som kjøres når hendelsen skjer
});
Del Forklaring
element HTML-elementet vi lytter på
"hendelse" Hvilken hendelse vi lytter etter (f.eks. "click")
function() { ... } Koden som kjøres når hendelsen skjer

Eksempel: Klikk-hendelse

Det enkleste eksempelet - skriv en melding til konsollen hver gang noen klikker på en knapp:

let knapp = document.querySelector("#minKnapp");

knapp.addEventListener("click", function() {
    console.log("Knappen ble klikket!");
});

Hver gang brukeren klikker på knappen, skrives "Knappen ble klikket!" til konsollen.

Eksempel: Endre tekst ved klikk

Her endrer vi innholdet i en overskrift når brukeren klikker på en knapp:

<h1 id="tittel">Hei!</h1>
<button id="endreKnapp">Endre tittel</button>
let knapp = document.querySelector("#endreKnapp");
let tittel = document.querySelector("#tittel");

knapp.addEventListener("click", function() {
    tittel.textContent = "Tittelen er endret!";
});

Når brukeren klikker på knappen, endres teksten i <h1> fra "Hei!" til "Tittelen er endret!".

Flere hendelser på samme element

Et element kan ha så mange event listeners du vil - både for ulike hendelser og flere listeners for samme hendelse:

let boks = document.querySelector("#minBoks");

boks.addEventListener("mouseover", function() {
    boks.style.backgroundColor = "lightblue";
});

boks.addEventListener("mouseout", function() {
    boks.style.backgroundColor = "white";
});

Her endrer boksen farge når musen er over den, og går tilbake til hvit når musen forlater.

let knapp = document.querySelector("#minKnapp");

knapp.addEventListener("click", function() {
    console.log("Første listener kjører!");
});

knapp.addEventListener("click", function() {
    console.log("Andre listener kjører også!");
});

Begge funksjonene kjører når knappen klikkes - de overskriver ikke hverandre. De kjører i den rekkefølgen de ble lagt til.

Vanlige hendelser

Mus

Event Utløses når
click Brukeren klikker
dblclick Brukeren dobbeltklikker
mouseover Musen beveger seg over elementet
mouseout Musen forlater elementet
mousedown Museknappen trykkes ned
mouseup Museknappen slippes

Tastatur

Event Utløses når
keydown En tast trykkes ned
keyup En tast slippes

Skjema og input

Event Utløses når
submit Et skjema sendes inn
input En input-verdi endres (live, ved hvert tastetrykk)
change En input-verdi endres (når feltet mister fokus)
focus Et felt får fokus (brukeren klikker i det)
blur Et felt mister fokus (brukeren klikker utenfor)

input vs change

input reagerer på hvert eneste tastetrykk - perfekt for live-søk og sanntidsoppdateringer. change reagerer først når brukeren er ferdig og klikker utenfor feltet.

Andre events

Event Utløses når
load Siden eller et bilde er ferdig lastet
scroll Brukeren scroller på siden
resize Nettleservinduet endrer størrelse

Informasjon om hendelsen

Når en hendelse skjer, lager JavaScript automatisk et event-objekt som inneholder informasjon om hva som skjedde. Du får tilgang til det ved å legge til en parameter i funksjonen:

knapp.addEventListener("click", function(event) {
    console.log(event);  // Hele event-objektet
});

Navnet event

Du kan kalle parameteren hva du vil, men event eller e er mest vanlig:

// Disse gjør det samme
knapp.addEventListener("click", function(event) { ... });
knapp.addEventListener("click", function(e) { ... });

Nyttige egenskaper

Egenskap Beskrivelse Eksempel
event.target Elementet hendelsen skjedde på <button>Klikk</button>
event.type Typen hendelse "click"
event.key Hvilken tast som ble trykket "Enter", "a"
knapp.addEventListener("click", function(event) {
    console.log(event.target);   // Elementet som ble klikket
    console.log(event.type);     // "click"
});

Hvilket element ble klikket?

event.target gir deg elementet som utløste hendelsen. Dette er nyttig når du vil vite hva som ble klikket:

document.addEventListener("click", function(event) {
    console.log("Du klikket på:", event.target);
    console.log("Det var en:", event.target.tagName);
});

For eksempel, hvis du klikker på en <button>, vil event.target.tagName være "BUTTON".

Tastetrykk

Du kan lytte etter tastetrykk og reagere på bestemte taster:

document.addEventListener("keydown", function(event) {
    console.log("Du trykket:", event.key);
});

event.key gir deg navnet på tasten som ble trykket. Noen vanlige verdier:

Tast event.key
Enter "Enter"
Escape "Escape"
Mellomrom " "
Pil opp "ArrowUp"
Pil ned "ArrowDown"
Pil venstre "ArrowLeft"
Pil høyre "ArrowRight"
Bokstav a "a"
Tall 1 "1"

Eksempel: Reagere på bestemte taster

Du kan bruke if-setninger for å sjekke hvilken tast som ble trykket og gjøre forskjellige ting:

document.addEventListener("keydown", function(event) {
    if (event.key === "Enter") {
        console.log("Du trykket Enter!");
    }

    if (event.key === "Escape") {
        console.log("Du trykket Escape!");
    }
});

Eksempel: Styre noe med piltastene

En rød boks som brukeren kan flytte rundt på siden med piltastene:

<div id="spiller" style="width: 50px; height: 50px; background: red; position: absolute; top: 100px; left: 100px;"></div>
let spiller = document.querySelector("#spiller");
let x = 100;
let y = 100;

document.addEventListener("keydown", function(event) {
    if (event.key === "ArrowUp") {
        y = y - 10;
    }
    if (event.key === "ArrowDown") {
        y = y + 10;
    }
    if (event.key === "ArrowLeft") {
        x = x - 10;
    }
    if (event.key === "ArrowRight") {
        x = x + 10;
    }

    spiller.style.top = y + "px";
    spiller.style.left = x + "px";
});

Her kan du flytte en rød boks med piltastene!

Skjemaer

Skjemaer har en innebygd oppførsel: når du trykker "Send", laster nettleseren siden på nytt. Som oftest vil vi stoppe dette og håndtere dataen med JavaScript i stedet.

Stoppe standard-oppførsel

event.preventDefault() stopper elementets standard-oppførsel:

let skjema = document.querySelector("form");

skjema.addEventListener("submit", function(event) {
    event.preventDefault();  // Stopper siden fra å laste på nytt

    let navn = document.querySelector("#navn").value;
    console.log("Sendt inn: " + navn);
});

Ikke glem preventDefault()

Uten event.preventDefault() vil siden laste på nytt når skjemaet sendes, og du mister alt JavaScript har gjort.

Komplett skjema-eksempel

Et registreringsskjema som viser en velkomstmelding i stedet for å laste siden på nytt:

<!DOCTYPE html>
<html lang="no">
<head>
    <title>Skjema</title>
</head>
<body>
    <form id="registrering">
        <label for="navn">Navn:</label>
        <input type="text" id="navn" required>

        <label for="epost">E-post:</label>
        <input type="email" id="epost" required>

        <button type="submit">Registrer</button>
    </form>

    <p id="melding"></p>
    <script src="script.js"></script>
</body>
</html>
let skjema = document.querySelector("#registrering");
let melding = document.querySelector("#melding");

skjema.addEventListener("submit", function(event) {
    event.preventDefault();

    let navn = document.querySelector("#navn").value;
    let epost = document.querySelector("#epost").value;

    melding.textContent = "Velkommen, " + navn + "! Vi sender info til " + epost;
});

Tekstfelt

Med input-eventen kan du reagere i sanntid mens brukeren skriver:

<input type="text" id="sokefelt" placeholder="Søk...">
<p id="resultat"></p>
let input = document.querySelector("#sokefelt");
let resultat = document.querySelector("#resultat");

input.addEventListener("input", function(event) {
    resultat.textContent = "Du skrev: " + event.target.value;
});

event.target.value gir deg det som står i tekstfeltet akkurat nå.

Eksempel: Telle tegn

Vis brukeren hvor mange tegn de har skrevet, slik man ofte ser i meldingsapper:

<textarea id="melding" maxlength="200" placeholder="Skriv en melding..."></textarea>
<p id="teller">0 / 200 tegn</p>
let tekstfelt = document.querySelector("#melding");
let teller = document.querySelector("#teller");

tekstfelt.addEventListener("input", function(event) {
    let antall = event.target.value.length;
    teller.textContent = antall + " / 200 tegn";
});

Eksempel: Live-filtrering

Filtrer en liste mens brukeren skriver - elementer som ikke matcher søketeksten skjules automatisk:

<input type="text" id="sok" placeholder="Filtrer frukt...">
<ul id="liste">
    <li>Eple</li>
    <li>Banan</li>
    <li>Appelsin</li>
    <li>Druer</li>
    <li>Mango</li>
</ul>
let sokefelt = document.querySelector("#sok");
let elementer = document.querySelectorAll("#liste li");

sokefelt.addEventListener("input", function(event) {
    let soketekst = event.target.value.toLowerCase();

    for (let element of elementer) {
        let tekst = element.textContent.toLowerCase();

        if (tekst.includes(soketekst)) {
            element.style.display = "";       // Vis elementet
        } else {
            element.style.display = "none";   // Skjul elementet
        }
    }
});

Her filtreres listen mens du skriver - skriv "ba" og bare "Banan" vises!

Musebevegelser

Du kan reagere på at brukeren beveger musen over et element. Dette kalles ofte en hover-effekt - noe endrer seg visuelt når musen er over elementet, og går tilbake til normalt når musen flyttes bort.

Hover-effekt med JavaScript

let boks = document.querySelector("#minBoks");

boks.addEventListener("mouseover", function() {
    boks.style.transform = "scale(1.1)";
});

boks.addEventListener("mouseout", function() {
    boks.style.transform = "scale(1)";
});

CSS er ofte bedre for hover

For enkle hover-effekter er CSS-transitions enklere og raskere. Bruk JavaScript for hover-effekter som krever logikk (f.eks. vise/skjule innhold).

Vanlige feil

Elementet finnes ikke ennå

// FEIL - script i <head>, elementet finnes ikke ennå
let knapp = document.querySelector("#minKnapp");
knapp.addEventListener("click", function() { ... });
// Error: Cannot read properties of null

Løsning: Plasser <script> nederst i <body>, slik at HTML-elementene er lastet først. Se Koble JavaScript til HTML for mer.

Glemmer å hente verdien fra input

// FEIL - du får hele input-elementet, ikke teksten
let tekst = document.querySelector("#mittFelt");
console.log(tekst);  // <input type="text" id="mittFelt">

// RIKTIG - bruk .value for å hente teksten
let tekst = document.querySelector("#mittFelt").value;
console.log(tekst);  // "det brukeren skrev"

Tall fra input er tekst

// FEIL - input-verdier er alltid tekst
let tall1 = document.querySelector("#tall1").value;  // "5" (tekst)
let tall2 = document.querySelector("#tall2").value;  // "3" (tekst)
console.log(tall1 + tall2);  // "53" (setter sammen tekst!)

// RIKTIG - konverter til tall med Number()
let tall1 = Number(document.querySelector("#tall1").value);  // 5 (tall)
let tall2 = Number(document.querySelector("#tall2").value);  // 3 (tall)
console.log(tall1 + tall2);  // 8

Referanse

Se DOM-referansen for en komplett oversikt over events, skjemahåndtering og DOM-traversering.

Komplett eksempel: Enkel teller

En teller med pluss-, minus- og nullstill-knapper. Tre knapper som alle endrer det samme tallet:

<!DOCTYPE html>
<html lang="no">
<head>
    <title>Teller</title>
</head>
<body>
    <h1 id="tall">0</h1>
    <button id="pluss">+</button>
    <button id="minus">-</button>
    <button id="nullstill">Nullstill</button>
    <script src="script.js"></script>
</body>
</html>
let tallElement = document.querySelector("#tall");
let plussKnapp = document.querySelector("#pluss");
let minusKnapp = document.querySelector("#minus");
let nullstillKnapp = document.querySelector("#nullstill");

let teller = 0;

plussKnapp.addEventListener("click", function() {
    teller++;
    tallElement.textContent = teller;
});

minusKnapp.addEventListener("click", function() {
    teller--;
    tallElement.textContent = teller;
});

nullstillKnapp.addEventListener("click", function() {
    teller = 0;
    tallElement.textContent = teller;
});

Komplett eksempel: Kalkulator

En enkel kalkulator der brukeren skriver inn to tall og får summen:

<input type="number" id="tall1" placeholder="Tall 1">
<input type="number" id="tall2" placeholder="Tall 2">
<button id="leggSammen">+</button>
<p id="svar"></p>
document.querySelector("#leggSammen").addEventListener("click", function() {
    let a = Number(document.querySelector("#tall1").value);
    let b = Number(document.querySelector("#tall2").value);
    document.querySelector("#svar").textContent = "Svar: " + (a + b);
});

Komplett eksempel: Gjøremålsliste

En enkel app der du kan legge til og fjerne gjøremål:

<!DOCTYPE html>
<html lang="no">
<head>
    <title>Gjøremål</title>
</head>
<body>
    <h1>Mine gjøremål</h1>
    <input type="text" id="nyOppgave" placeholder="Skriv en oppgave...">
    <button id="leggTil">Legg til</button>
    <ul id="liste"></ul>
    <script src="script.js"></script>
</body>
</html>
let input = document.querySelector("#nyOppgave");
let knapp = document.querySelector("#leggTil");
let liste = document.querySelector("#liste");

knapp.addEventListener("click", function() {
    let tekst = input.value;

    // Ikke legg til tomme oppgaver
    if (tekst === "") {
        return;
    }

    // Lag et nytt liste-element
    let li = document.createElement("li");
    li.textContent = tekst;

    // Gjør at man kan klikke på oppgaven for å fjerne den
    li.addEventListener("click", function() {
        li.remove();
    });

    // Legg til i listen og tøm inputfeltet
    liste.appendChild(li);
    input.value = "";
});

// La brukeren trykke Enter for å legge til
input.addEventListener("keydown", function(event) {
    if (event.key === "Enter") {
        knapp.click();  // Simulerer et klikk på knappen
    }
});

Her bruker vi flere konsepter sammen:

  • click-event for å legge til nye oppgaver
  • keydown-event for å støtte Enter-tasten
  • document.createElement() for å lage nye elementer (se DOM)
  • Nøstede event listeners (klikk på en oppgave for å fjerne den)

Oppsummering

Konsept Beskrivelse
addEventListener Koble en hendelse til et element
"click" Brukeren klikker
"keydown" Brukeren trykker en tast
"submit" Et skjema sendes inn
"input" Brukeren skriver i et felt (live)
event.target Elementet hendelsen skjedde på
event.key Hvilken tast som ble trykket
event.target.value Verdien i et input-felt
event.preventDefault() Stopp standard-oppførsel