Gyakran szembe jött már velem az a probléma, hogy több sticky, azaz ragadós menüre volt szükség. Sokan, sokféle eszközt használnak erre, de sokszor legegyszerűbb a saját. Most leírom hogyan kell egy ilyet megcsinálni.
A sticky menü általában akkor kell, ha a főmenüt, vagy annak egy részét fixen oda akarjuk ragasztani, amikor görgetés közben a böngészőben elértük annak pozícióját. Ehhez a generált HTML kód vizsgálatára és megváltoztatására van szükség, amit Javascript-ben fogok megírni. A PHP-vel ellentétben, ami szerveroldalon fut, a Javascript-et a kliensoldalon használjuk. A kliens oldal maga a böngésző, amit a weboldalunk látogatója lát és, azaz kattint, görget és úgy általában használ. A kliens oldal elemei a böngésző által feldolgozott és megjelenített, generált HTML kód. Ebben szeretnénk most és tudunk is turkálni a JavaScripttel.
Ahhoz, hogy a JavaScriptet hatékonyan tudjuk használni természetesen elengedhetetlen a HTML és a CSS használata. Mindezekről most nem írok hosszan, de akit érdekel az erről szóló cikkem, az ezt olvassa el.
A feladat tehát annyi, hogy egy oldal adott eleméhez érve azt „odaragasztjuk” a képernyő tetejére, tehát a látogató ezt mindig eléri akkor is, így kényelmesen tud navigálni az egyes lehetőségek között és nem kell mindig visszagörgetnie ehhez a részhez. Meg kell csinálnunk természetesen visszafelé is, ha felfelé hagyjuk el ezt a részt, akkor visszatesszük a normál, azaz a „ragadásmentes”, eredeti állapotába.
Mi kell ehhez? Azért szeretem a fejlesztői munkát, mert nagyon kreatív. Ezt a feladatot ugyanis többféleképpen meg lehet oldani, és mi tudjuk kiválasztani, hogy melyik a szimpatikus. Nem az a lényeg, hogy mennyire elegáns a kód, hanem az, hogy működjön, az ügyfél pedig elégedett legyen. Persze, ha fenntartható kódot szeretnénk, akkor erre is figyeljünk, de ez a cikk most nem erről szól.
- Kiszámoljuk az összes olyan elem magasságát az oldal tetejétől addig a pontig, ahol a sticky menü elkezdődik.
- Inicializálunk az onscroll eseményfigyelőt (ún. event listener), ami folyamatosan figyel méghozzá csak akkor, ha görgetünk, egyébként nem csinál semmit. A Javascriptben vannak beépített, a HTML szabványhoz tartozó, és az adott böngészőben működő és vannak az egyedi, általunk írt eseményfigyelők. Mi most az alapértelmezett, minden böngészőben elérhető onscroll eseményfigyelőt fogjuk használni.
- A görgetés közben figyeljük hol áll a pozíció és ha elérte a kívánt magasságot (azaz a látogató scrollozás közben odaért a kívánt elemhez), akkor hozzáadunk a body DOM elemhez valamilyen egyedi osztályt, hogy majd CSS-sel tudjunk rá hivatkozni. Ha újra elhagyta a látogató ezt a pozíciót, tehát fölfelé görgetett, akkor pedig levesszük róla ugyanezt az osztályt. Így a kétféle állapotot meg tudjuk majd különböztetni egymástól, így annak pozícióját is el tudjuk különíteni.
Csinálhatjuk jQuery-vel, vagy normál Javascripttel is. Én most az utóbbit fogom bemutatni, mert az mindenhol működik, és nem kell hozzá semmi, bárhol, bármilyen környezetben alkalmazható, dependency, azaz függőség nélkül. A dependency azt jelenti, hogy egy adott metódus csak egy másik metódussal együtt működik. Ilyen a jQuery is, ahhoz, hogy az általa megadott egyszerűsített eszközöket használni tudjuk, előbb be kell tölteni a böngészőnek a jQuery-t. A Javascript történetéről most nem írok le egy regényt, akit érdekel, az erre nézelődjön., de ez az oldal is jó kiindulópont lehet.
// Definiáljuk a DOM elemet, hogy később hivatkozhassunk rá.
// Ehhez az elemhez fogjuk később az egyedi osztályt (class) adni
// Azért a elemhez adjuk, mert ez van majdnem legfelül a HTML hierarchiában, így az ez alatti bármely elemre tudunk hivatkozhatunk
const theBody = document.querySelector(`body`);
// Képernyő szélessége: ez opcionális, használhatjuk pl. egy feltételnél, hogy az egész csak akkor fusson le, ha pl. mobilnézetben vagyunk
var screenWidth = window.innerWidth;
// Az első elem, aminek az oldal tetejétől ki kell számolnunk a magasságát
var headerDiv = document.querySelector(`#header-outer`);
// A többi kiszámolandó elem ez alatt az elem alatt található, ami alatt ki kell számoljuk az összes elem magasságát
var mainDiv = document.querySelector(`#ajax-content-wrap .container-wrap .container.main-content div.row`);
// Az előző elem alatti két gyerek elem, mindkettő magassága kell, mivel ez után következik maga a menü
var firstChildDiv = mainDiv.children[0];
var secondChildDiv = mainDiv.children[1];
// Mivel megvan minden elem, kiszámoljuk ki az összes magasságát és összeadjuk
var totalHeight = headerDiv.offsetHeight + firstChildDiv.offsetHeight + secondChildDiv.offsetHeight;
// Görgetés eseményfigyelő (scroll event listener), ez csak akkor fut, amikor görgetünk
window.onscroll = function()
{
// Ez a böngészőablak oldal tetejétől számolt magassága pixelben
var windowPageOffset = window.pageYOffset;
// Ha az oldal tetejétől legörgetett magasság nagyobb, mint az összeszámolt elemek magassága,
// akkor elértük a sticky menüt, azaz azt az elemet, amit oda akarunk ragasztani
if ( windowPageOffset >= totalHeight ) {
theBody.classList.add("sticky_submenu");
} else {
// Ha ennek ellenkezője igaz, tehát elhagytuk fölfelé scrollozás közben ezt a területet
// akkor visszaállítjuk az eredeti állapotot
theBody.classList.remove("sticky_submenu");
}
};
Ezeken a képernyőmentéseken elmagyarázom melyik rész, mit csinál. Van benne egy kis HTML alapozó is, aki még mindig nem értené, hogyan kell hivatkozni egy adott HTML elemre.
Annyit csinálok, amit a háromlépéses részben már leírtam, megnézem az elemek magasságát, összeadom, majd a görgetésfigyelővel megnézem elérte már az adott pozíció ezt az értéket vagy már meg is haladta. Ha ez igaz, akkor hozzáadom a body elemhez a `sticky_submenu` nevű osztályt, amit CSS-ben előzőleg már definiáltam. Innentől kezdve, ha a body elem rendelkezik ezzel az osztállyal, akkor az lesz rá érvényes, egyébként nem.
body.sticky_submenu .nectar-sticky-row-wrap.nectar-sticky-row-wrap--top_after_nav {
position: fixed;
top: 44px;
z-index: 99;
width: 100%;
left: 0;
}
Remélem mindenkiben sikerült felkelti az érdeklődést hogyan is működnek a DOM manipulációk és innen megnyílik egy új fejezet a Javascript metódusok és a HTML elemek módosításának fejezetében. Rövid és eredményes kódolást!