Horizontaal verschuivend menu
Onderaan deze bladzijde zie je een menu. Als je er met de muis overheen gaat of het aantikt op een aanraakscherm, verschuift
het, zodat je door het menu kunt 'bladeren'. Daarbij geldt: Als je de muis naar rechts verschuift, gaat het menu naar links, en
omgekeerd.
Op deze pagina wordt verteld hoe je dat maakt.
Dit verhaal is een bewerking van code bij een artikel in Webdesigner Magazine 99 (november 2017), pag. 64 en 65. Het oorspronkelijke
script is niet meer beschikbaar op internet. Een auteur staat niet bij het artikel genoemd. Voor deze site is de code wat
vereenvoudigd, verbeterd en is de opmaak verfraaid.
Dit blad wordt sinds eind november 2017 niet meer gemaakt.
De code van het voorbeeld kun je downloaden om zelf te gebruiken.
- Er worden twee items besproken:
- De werking van het script.
- Toepassen in je eigen site.
- De werking van het script
- De code bestaat uit HTML, CSS en JavaScript. Alle code staat in het document.
- Het menu staat in één <div>-tag, die dient als container. De menu-items zijn aparte blokken
binnen die container. Als het menu schuift, is dat in feite de container die de menu-item-blokken met zich mee neemt.
- HTML
- De HTML bestaat uit eacute;én enkele <div>-tag met id="block"". Deze dient als container voor het hele menu. De beweging wordt geregeld door JavaScript, dat wordt geactiveerd met onmouseover. De aangeroepen function verandert de CSS.
- De afzonderlijke menu-items worden gemaakt met <div>-tags die elk de klasse menu hebben. In elke <div>-tag staat een hyperlink (<a>-tag), die moet je zelf invoegen. In het voorbeeld op deze pagina staat alleen tekst.
- De opmaak van de menu-items wordt geregeld door CSS.
- Helemaal onderaan de pagina, vlak voor de </body>-tag, staat nog een <div>-tag die wordt gebruikt
om witruimte mee te maken, zodat ook de laatste tekstregels van het document leesbaar blijven en niet worden afgedekt door
het menu.
- CSS
- Voor de body wordt overflow-x: hidden ingesteld om te voorkomen dat er een horizontale schuifbalk ontstaat, omdat die de beleving van het menu verstoort.
- Daarna worden de afmetingen van de container (#block) vastgelegd. De breedte (hier: 1550px) moet groter zijn dan de breedte van alle menu-items bij elkaar, plus de witruimte tussen de items.
- Voor het verschuiven van #block is een transformatie gedefinieerd met cubic bezier. De translatie-afstand wordt berekend en in CSS gezet door het JavaScript
- #block is vastgepind aan de onderkant van het window. Verder is de z-index op 1 gezet. Het menu zweeft dus boven het document.
- De menu items staan in rechthoeken van 200 × 55 px; Voor de klasse .menu is box-sizing: border-box ingesteld. De genoemde afmetingen zijn dus de buitenkanten van de blokken.
- De blokken staan achter elkaar. Dat wordt geregeld door diaplay: inline-block. Met margin-left wordt de witruimte tussen de blokken iets vergroot.
- De witruimte onder aan de pagina wordt gemaakt met een lege div-tag. Deze heeft een inline-style: height:100px;
width:20px. De hoogte is in het voorbeeld een beetje groter dan de hoogte van #block. De breedte is arbitrair, maar
moet groter zijn dan nul.
- JavaScript
- Het JavaScript ziet er ingewikkelder uit dan het is. Als de muis-aanwijzer boven het menu zweeft, wordt de event-handler move(event) actief, door onmousemove. Omdat onmousemove een attrribuut is van de div--tag met id="block", werkt dus alleen op het blok dat de menu-items bevat.
- Zodra move(event) is aangeroepen wordt de X-positie van vde muis-pijl bepaald. Deze wordt opgeslagen in de globale variabele posX. Deze waarde wordt gebruikt als invoer voor de function map(), samen met de globale variabelen w (die bevat de breedte van het window, in px) en diff (die bevat de breedte van het menu-blok minus de breedte van het window.
- Het resultaat van de berekening door map() wordt naar beneden afgerond en opgeslagen in offset. Offset wordt
van teken veranderd en wordt gebruikt als waarde voor een horizontale translatie (verplaatsing). Die wordt in de CSS ingebracht
met block.style.transform.
- De variabele event waarmee map() wordt aangeroepen is standaard aanwezig in JavaScript. Deze variabele
bevat informatie over het laatste event dat door de browser is afgevuurd.
- Toepassen in je eigen site
- Download de .zip-file en pak hem uit. Bouw de code op in je document zoals op deze pagina is aangegeven.
- Voeg menu-items toe of verwijder ze door
<div class="menu">
-tags toe te voegen of te verwijderen in de container
<div id="block" onmousemove="mover(event)">
. - Voorzie de menu-items van <a>-tags om er links van te maken.
- Pas de CSS aan aan je wensen: Grootte en opmaak van de blokken (klasse menu). Let er op dat, als je de hoogte van
de blokken aanpast, je ook de hoogte van de container en de witruimte onderaan moet veranderen.
- Het menu moet breder zijn dan het breedste window dat in je site gebruikt kan worden.
Uitleg: Het menu in het voorbeeld is 1300px breed. In deze site (met de frames) is het window maximaal 600px breed. Maar als je dit voorbeeld bekijkt buiten de frameset (klik HIER) in een scherm dat bijv. 1920px breed is, dan zie je het hele menu en er blijft links en rechts ruimte over. Als je er met de muis overheen gaan beweegt het een beetje heen en weer, maar precies andersom als bij een 'correct te brede' . Dat vind ik niet mooi.
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>
body { overflow-x: hidden; }
#block {
width: 1550px;
height: 85px;
transition: transform 0.7s cubic-bezier(0.36, 0.36, 0.59, 1);
position: fixed;
bottom: 0;
z-index: 1;
}
.menu {
box-sizing: border-box;
background: #09c;
padding: 20px;
color: #fff;
font-weight: bold;
font-size: 120%;
text-align: center;
width: 200px;
height: 55px;
display: inline-block;
margin-left: 10px;
}
</style>
(Zet dit ergens in de <BODY>, bijvoorbeeld aan het begin.
Belangrijk is dat het JavaScript komt na de HTML).
<div id="block" onmousemove="mover(event)">
<div class="menu">Home</div>
<div class="menu">Handig</div>
<div class="menu">Fractals</div>
<div class="menu">HTML</div>
<div class="menu">Varia</div>
<div class="menu">Webmasterij.nl</div>
</div>
<script>
var posX = 0;
var offset = 0;
var w = document.body.clientWidth;
var block = document.getElementById('block');
var diff = 1300 - w;
function map(n, start1, stop1, start2, stop2) {
return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
}
function mover(e) {
posX = e.clientX;
offset = Math.floor(map(posX, 0, w, 0, diff));
offset = -1 * offset;
block.style.transform = "translateX(" + offset + "px)"
}
</script>
(Zet dit aan het eind van de <BODY>, net voor de </BODY>-tag.)
<div style="height:100px; width:20px;"></div>