CSS alapú kép előtöltő (preloader)

Emlékszem, amikor először láttam JavaScriptet. Az id Software oldalán volt. A képek megváltoztak, amikor föléjük vitted az egeret. Ez volt a kötelező onmouseover, onmouseout páros, ami a web fejlődésének egy korszakát fémjelezte. Ez történelem.

Ma ez már a CSS feladata. Egészen pontosan a hover pszeudoosztályé. Ennek segítségével végezzük el eme kötelező formagyakorlatot.

A baj csak az volt, hogy a képek nem töltődtek le mindaddig, amíg először meg nem akartuk jeleíteni őket. Így az over esemény után kellett letölteni a hozzá tartozó képet, ami mindig egy kis villanást eredményezett. (Hasonlóan ma is a CSS-sel.) Ezért már az ős időkben is divat volt a képek előtöltése. Ez valahogy így történt:

var ims = new Array ("elso.jpg", "masodik.jpg", "harmadik.jpg"); var i; for (i=0; i<ims.length; i++) { var img = new Image(); img.src = ims[i]; }

Az ehhez hasonló szkriptek sok helyen túlélték a dinoszauruszokat (például a Microsoft Vistás oldalán), de könnyen belátható fő hiányosságuk: A képek listáját pontosan karban kell tartani. Így vagy úgy, könnyen előfordulhat egy változás az oldal megjelenésében, amit nem követünk pontosan a szkriptben (például a Microsoft Vistás oldalán).

Konkurens megoldás: két állás egy képben

Megoldás lehet még, ha a "gomb" két állását egymás mellé másoljuk egy képbe. Így egy olyan képet kapunk, ami pontosan kétszerese lesz a kívánt magasságnak (vagy szélességnek, ha az X tengelyen dolgozunk). A két kép közül csak az első fog látszani, mert a második "kilóg" az elem területéről. A CSS lehetőséget ad a háttérkép pozícionálására, így aktív állásban nincs más dolgunk, mint a background-position adott értékét az elletétére változtatni (top -> bottom vagy left->right), és már is az ábra másik állása (a dupla képünk másik fele) lesz látható.

A módszer előnye, hogy nem kell hozzá JavaScript, hátránya viszont, hogy logikailag kevésbé átlátható helyzetet teremt, és előállítása is nehezebb (vagy megkötésekkel jár).

Az új era harcosa: a CSS alapú preloader

Egy nagyon egyszerű szkriptről van szó, ami végigmegy a betöltött stíluslapokon, és betölti az összes általuk hivatkozott képet. Eredetileg nem akartam publikálni, de miután az Apple csilli-villi Leopard Sneak Peak-jén is villogni láttam a gombokat, arra gondoltam, talán épp egyszerűségében lakozik tökéletessége. (Najó, ez talán így sok.. :)

Persze a CSS írási stílustól függően egykét "fölösleges" kép is betöltődhet, amik konkrétan ezen oldalon nem szerepelnének, de a site-ot böngészve előbb-utóbb előkerülnek, úgyhogy nem veszítünk olyan sokat. (A plusz terhelés néhány statikus grafika betöltése, amiket a szerver valószínűleg cache-el.) A betöltés akkor történik, amikor a látogató már böngészi a teljesen kész oldalt. Én azt mondom, megéri egy kényelmesebb és biztonságosabb megoldásért.

function cssPreloadImages() { var i, j, img; for (i=0; i<document.styleSheets.length; i++) { var pos = document.styleSheets[i].href.lastIndexOf("/"); var cssDir = (pos != -1) ? document.styleSheets[i].href.substring(0, pos + 1) : ""; var rules = document.styleSheets[i].cssRules ? document.styleSheets[i].cssRules : document.styleSheets[i].rules; for (j=0; j<rules.length; j++) { var style = rules[j].style; if (style.backgroundImage.toLowerCase().substr(0,4) == "url(") { var filename = style.backgroundImage.substring(4, style.backgroundImage.length - 1); if (filename.indexOf("http://") != 0 && filename.indexOf("/") != 0) filename = cssDir + filename; var img = new Image(); img.src = filename; } } } } if (window.attachEvent) { // IE window.attachEvent("onload", cssPreloadImages); } else { // DOM window.addEventListener("load", cssPreloadImages, false); }

Két egymásba ágyazott ciklusról van szó. A külső (azaz i) ciklus végigmegy a beágyazott stíluslapokon. A belső (vagyis j) ciklus pedig az adott stíluslap egyes szabályain. Ahol háttérképet talál, ott betölti. Figyelni kell rá, hogy a képek elérési útja az egyes CSS fájlok elérési útjához van viszonítva, úgyhogy konvertálnunk kell a relatív hivatkozásokat (ami nem / karakterrel, vagy "http://" szöveggel kezdődik). Ezt az előzőleg kikalkulált cssDir változó segítségével tesszük meg. Az utolsó blokk késlelteti a szkript lefutását a dokumentum betöltődéséig. (Hiszen csak akkor biztos, hogy az összes CSS fájl rendelkezésre áll már).

A szkript használatához (az oldalon megszokott módon) elég csupán belinkelni, mondjuk a head szekcióban (nem számít, hogy a css-ek fölött vagy alatt, hiszen a szkript csak az oldal betöltődése után fut le):

<script type="text/javascript" src="csspreload.js"></script>

A forrás

Külső linkek

  • QuirksMode - Hozzáférés a CSS stíluslapokhoz