Verticale scroll-indicator I: puntjes
Als je een klein beetje naar beneden scrollt, verschijnen aan de rechterkant vier puntjes, op ongeveer halverwege de hoogte van het browserwindow. Het bovenste puntje is heeft een andere kleur dan de andere drie. Als je verder scrollt verschuift het bovenste puntje naar beneden, totdat je bijna aan het einde van het document bent. Dan is het vierde puntje gekleurd.
Op deze pagina wordt uitgelegd hoe je zoiets maakt. De code van het voorbeeld staat onderaan de pagina. Je kunt de code ook downloaden om zelf te gebruiken.
- Er worden twee items besproken:
- De werking van het script.
- Toepassen in je eigen site.
- Inspiratie voor dit item is ontstaan door de website AFB-toners.nl.
Voor deze site heb ik het effect nagebouwd, althans iets wat er veel op lijkt.
- De werking van het script
- De code bestaat uit HTML, CSS en JavaScript.
- HTML
- De HTML bestaat uit een enkele <div>-tag met de klasse class="container" (voor de opmaak) en id="container" (voor referentie door JavaScript). Deze container dient om de vier puntjes bij elkaar te houden en het geheel te positioneren in het document.
- Behalve de <div>-tags voor de puntjes bevat de container geen andere content.
- Voor elk puntje is een <div>-tag met class="puntje" (voor de opmaak) en id="Px" (voor referentie door JavaScript). De id's zijn uniek per puntje en vormen een oplopende reeks P1, P2, P3, …. De nummering begint bij 1 en mag geen gaten hebben.
- De<div>-tags voor de puntjes bevatten geen andere content.
- De HTML mag overal in het document staan. Helemaal bovenaan is een goede plek.
- CSS
- De CSS van het voorbeeld omvat drie blokken, voor de klassen container, puntje en actief.
- De klasse container dient om de vier puntjes bij elkaar te houden en in het window te positioneren.
- De position is fixed. Doordat top is ingesteld op 45%, blijven de puntjes netjes op hun plaats, ook als de grootte van het window wordt veranderd.
- De breedte van de container is smal gehouden om te zorgen dat de puntjes onder elkaar blijven staan. De z-index is hoog, zodat de puntjes altijd zichtbaar zijn.
- Bij het laden van de pagina staat de visibility op hidden, zodat de puntjes niet zichtbaar zijn. Bij scrollen
wordt de visibility op visible gezet door JavaScript.
- De klasse dient voor de vormgeving en de opmaak van de blauwe puntjes. Die worden gemaakt met een blok met afmetingen 0px × 0px, maar met een border van 6px breed. Door de border-radius op 50% te zetten, ontstaat het rondje.
- Om de puntjes niet te opvallend te maken zijn ze een beetje transparant gemaakt met opacity: 50%.
- Positionering binnen de container wordt geregeld met behulp van margin.
- Als er wordt gescrolled wordt een puntje wat groter en verandert van kleur. Dat gebeurt door met JavaScript de klasse actief aan het puntje toe te voegen.
- Omdat de border-width 8px is, wordt left veranderd van 0 naar -2px. Daardoor blijven de puntjes netjes onder elkaar staan.
- Bij het wisselen van de kleur bewegen de puntjes een beetje. Daardoor wordt de gebruiker geattendeerd op het veranderen
van de puntjes.
- JavaScript
- Het JavaScript begint met de declaratie van een drietal variabelen: yPerc, i en aa. Dit zijn alle
drie hulpvariabelen, o.a. bedoeld om dubbel rekenwerk te voorkomen.
In yPerc bevat de afstand waarover is gescrolled als percentage van de hoogte van het document en wordt met elke scroll-actie bijgewerkt. i is een loopteller en in aa wordt een referentie naar de container opgeslagen. - Daarna is er een event-listener die actief wordt als de pagina is geladen. Deze stelt aa in en maakt event-listeners voor scrollen en resizen van het window. Deze drie listeners laten de function puntjes() starten.
- De function puntjes() is de spil in het verhaal.
- Als eerste worden de puntjes verborgen.
- Er een mogelijkheid dat de puntjes niet allemaal zichtbaar zijn als het document-gebied van het window niet hoog genoeg is. Om dat te voorkomen wordt de uitvoering van puntjes() gestopt als het document-gebied van het window minder dan 400px hoog is.
- Als de uitvoering van puntjes() verder kan, wordt eerst berekend hoever er is gescrolled als percentage van de gerenderde hoogte van het document. Dat wordt opgeslagen in yPerc. Als yPerc meer is dan 2 worden de puntjes weer zichtbaar gemaakt.
- Vervolgens worden alle puntjes inactief (= blauw) gemaakt door de klasse actief te verwijderen.
- Daarna wordt éńn puntje actief (= rood en een beetje groter) gemaakt door er de klasse actief aan
toe te voegen:
• Als yPerc < 15 wordt het bovenste puntje actief.
• Als 15 ≤ yPerc < 40 wordt het tweede puntje actief.
• Als 40 ≤ yPerc < 65 wordt het derde puntje actief.
• Als yPerc ≥ 65 wordt het vierde puntje actief.
- Toepassen in je eigen site.
- Download de zip-file en pak hem uit. Bouw de code op zoals hieronder is aangegeven.
- Pas het uiterlijk van puntjes aan aan je eigen wensen. De CSS-eigenschappen die de kleur en de breedte van de border bepalen kun je zonder meer veranderen. Kies de kleuren niet te opvallend, zorg wel dat ze niet wegvallen tegen de achtergrond en dat er voldoende contrast is met de content zodat ze goed zichtbaar blijven.
- Als je de puntjes aan de linkerkant van het window wilt hebben, vervang je right door left in de klasse
container.
- Het is mogelijk om puntjes toe te voegen. Dat vergt een vrij grote ingreep. Het gaat als volgt:
- Voeg aan de HTML, binnen de container, <div>-tags toe met klasse puntje en id="P5", "P6", enz.
- Pas de JavaScript-function puntjes() aan:
• Verhoog de minimale hoogte van het window (nu 400px) waarbij de puntjes zichtbaar zijn.
• In de regelfor (i=1; i<=4; i++)
moet de eindwaarde van de for-loop gelijk worden gemaakt aan het aantal puntjes.
• Pas de voorwaarden aan (variabele yPerc) voor het actief maken van een puntje.
- Wijzig de waarde van top in de klasse container. Als er meer puntjes zijn moet top lager worden. Dit getal moet een percentage zijn.
- Het is lastig om aan te geven hoe je percentages en grenswaarden moet kiezen. Met een beetjes proberen kom je er wel.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
De code van het voorbeeld ziet er als volgt uit:
(Zet dit in de <HEAD>).
<style>
.container {
position: fixed;
top: 45%;
right: 15px;
width: 45px;
height: 150px;
z-index: 9999;
visibility: hidden;
}
.puntje {
position: relative;
width: 0;
height: 0;
border: 6px solid navy;
border-radius: 50%;
margin: 20px 15px;
opacity: 50%;
}
.actief {
border-color: #d00;
transition: all .5s;
border-width: 8px;
left:-2px;
}
</style>
<script>
window.addEventListener("load", function() {
aa = document.getElementById('container');
window.addEventListener("resize", puntjes);
window.addEventListener("scroll", puntjes);
puntjes();
});
var yPerc, i, aa;
function puntjes() {
// Verberg de puntjes
aa.style.visibility = "hidden";
// Alleen tonen als er minstens 400px hoogte is voor het document
if (window.innerHeight < 400) return;
// Hoe ver is er gescrolled?
yPerc = 100 * window.pageYOffset / document.body.clientHeight;
// Er moet minstens 2% zijn gescrolled
if (yPerc > 2) aa.style.visibility = "visible";
// Zet alle puntjes inactief
for (i=1; i<=4; i++)
document.getElementById('P'+i).classList.remove('actief');
// Bepaal actief te maken puntje en activeer dat
if (yPerc < 15) document.getElementById('P1').classList.add('actief');
else if (yPerc >= 15 && yPerc < 40)
document.getElementById('P2').classList.add('actief');
else if (yPerc >= 50 && yPerc < 65) document.getElementById('P3').classList.add('actief');
else document.getElementById('P4').classList.add('actief');
}
</script>
(Zet dit "ergens" in de <BODY>, bijvoorbeeld aan het begin).
<div id="P1" class="puntje"></div>
<div id="P2" class="puntje"></div>
<div id="P3" class="puntje"></div>
<div id="P4" class="puntje"></div>
</div>