Kop 1

tagline

Leerdoelen

In deze reeks maak je kennis met de Intersection Observer web API.
Deze kan worden ingezet om te zien welke elementen in een scrollend document in de viewport (of een ander parent-element waarbinnen gescrolled wordt) verschijnt.
Documentatie is te vinden op:
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API.
Deze informatie is handig bij:

  • het maken van lazy-loading van afbeeldingen of andere inhoud als de pagina scrollt.
  • Om 'oneindig scrollende' pagina's te maken
  • rapporteren van zichtbaarheid van adertenties om de opbrengsten in rekeking te brengen
  • het script te laten beslissen of er animaties of andere taken moeten plaatsvinden, zodat de gebruiker ze op het juiste moment ziet.

Vooral bij 'oneindig scrollende' pagina's is de Intersection Observer API onmisbaar omdat deze de prestaties van de pagina aanzienlijk verbetert.

De Intersection Observer API registreert wanneer een element binnenkomt of is.
Het geeft dan veel informatie terug: het element, of het doorsnijding geeft, de top, de hoogte, de onderzijde, het percentage dat zichtbaar is.

Intersection observer 0: het resultaat (00:01:31)

In deze reeks tutorials maken we een script dat ervoor zorgt dat bij het scrollen van een pagina de bijpassende link in het menu actief wordt.
Ondanks dat de hoogte van schuivende elementen sterk afhangt van de viewport wordt de bijpassende link in alle omstandigheden correct geactiveerd.

Als je dit filmpje gezien hebt, maak je zelf een pagina, met meerdere secties en een navigatie-menu dat er naar toe navigeert. In de CSS kun je de navigatie geleidelijk laten verlopen met:

            html {
              scroll-behaviour: smooth;
            }
          

In de volgende filmpjes werken we aan het script.

Intersection observer 1: JavaScript maakt links actief (00:11:44)

De pagina heeft een link met de de class actief en we maken een Javascript dat een geklikte link die class geeft.
Eerst maken we een variabele die alle linkjes uit het menu bevat.
Dit kan met .querySelectorAll();
Vervolgens een functie, die de aanwezige class actief verwijderd.
De variabele die alle linkjes bevat doorlopen we met een forEach() om de classList te bekijken. Bevat deze de class actief, dan wordt die met classList.remove() verwijderd.

Hierna een functie die omgekeerd aan een element (=parameter) die class actief toevoegt.
dat kan met classList.add().
Met een forEach doorlopen we alle linkjes en geven die een .addEventListener() die met een click-event een het element de class geeft.
Om te voorkomen dat de klik direct een sprong naar de interne link maakt en daarmee voorkomt dat onze acties worden uitgevoerd, geven we eerst een .preventDefault() en om tot slot toch nog naar de interne link te gaan: window.location = e.target.href;

Intersection observer 2: een observer maken (00:10:09)

Om de observer te maken, maken we eerst een variabele die alle secties bevat.
Vervolgens maken we een instantie aan met new IntersectionObserver().
Deze heeft 2 argumenten: een callbackfunctie, dit is een functie die wordt aangeroepen bij een intersectie-event en de opties.
De opties zijn een object, die we nu nog leeg laten.
De observer bekijkt een aantal elementen, en geeft entries terug.
We laten in de callback functie de entries maar loggen om te zien welke eigenschappen ze hebben.
We kijken erst maar naar 1 element: de tweede sectie uit onze variabele. We voeren die als argument in in observer.observe();
Na het bekijken van de uitvoer, passen we die aan zodat we het element krijgen en een boolean krijgen die aangeeft of er doorsnijding met de viewport is of niet.

Intersection observer 3: link aan entry koppelen (00:09:40)

Met entry.target.id is het mogelijk om de id van de sectie te achterhalen.
Dan moet je dus op zoek gaan naar de link uit de navigatie, dei daarnaartoe verwijst.
Met document.querySelector() is door een juist argument het element te vinden.
Het argument nav a[href="#deel2"] zal de link geven die naar de sectie met id deel2 linkt.
We maken dus een functie met parameter de id van de sectie die het element teruggeeft.
Met een aaneenrijging van strings en argumenten maak je dergelijke functie. In de console is die goed uit te testen.
Met deze functie kun je in de callback-functie de link vinden en die invoeren in de al bestaande functie om die link actief te maken.
De functie wordt alleen aangeroepen als de eigenschap isIntersecting true is.
Het geheel werkt dan voor sectie 2. Of er nu naar beneden of naar boven gescrolled wordt, bij verschijnen van sectie 2 wordt link 2 in het menu actief.

Intersection observer 4: intersection observe voor alle secties (00:04:08)

Als we van sectie 2 naar alle secties uitbreiden, moeten we door de nodeList van de secties met een forEach-loop de observer laten observeren.
Dit werkt opzicht niet zo feilloos. We voor het scrollen naar beneden.
Het wordt optimaler als we het opties object van de IntersectionObserver aan te passen.
Zie https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
We voeren een drempel in treshold en een negatieve marge bij rootMargin in.
Hierdoor moet er al en deel van de sectie binnen zijn voordat deze isIntersecting gegeven wordt. Hierdoor werkt het activeren beter.

Intersection observer 5: een andere benadering (00:03:12)

In plaats van het werken met een negatieve marge, kun je ook de IntersectionObserver naar specifieker laten kijken. Hier kiezen we voor de eerste paragraaf in de secties.
Dat betekent: observer.observe(sectie.getElementsByTagName('p')[0]);
Omdat deze elementen geen id hebben werkt de koppeling van de link niet.
Die koppelende functie moet dus niet naar entry.target.id zoeken maar naar de id van de parent van de betreffende paragraaf: entry.target.parentNode.id


Inleveren

  • Na afloop plaats je deze training online in je bewijzenmap;
  • Valideer jouw pagina's op Markup Validation Service van W3C.
  • De validatie icoontjes staan al in de footer. Code vind je bij https://github.com/Theo-denBlanken/validatie-W3C;
  • Plaats jouw uitwerking op in een aparte repository op GitHub
  • Maak in jouw GitHub-repo een README.md met daarin temnminste een link naar jouw online uitwerking.
  • Plaats de GitHub-link in ELO Magister.