Ezennel bele is csapnánk a lecsóba: első posztunkban a stylesheet elemek viselkedését fogjuk górcső alá venni egy bizonyos, az emberiség jövőjének vonatkozásában igen fontos szempontból.
A kód:
<HTML> <HEAD> <TITLE>Stylesheet onload/onerror test</title> <SCRIPT> // Standard startup section - to see what and when happens function myStartup() { alert("my startup code..."); } if (window.addEventListener) // W3C standard { window.addEventListener('load', myStartup, false); } else if (window.attachEvent) // Microsoft { window.attachEvent('onload', myStartup); } </SCRIPT> <SCRIPT> // This is the snippet to test function sheetLoaded(x) { alert(x.href + "\nSheet is loaded."); } function sheetError(x) { alert(x.href + "\nAn error occurred loading the stylesheet!"); } </SCRIPT> <link rel="stylesheet" type="text/css" href="local-test.css" onload="sheetLoaded(this)" onerror="sheetError(this)"> <link rel="stylesheet" type="text/css" href="local-missing.css" onload="sheetLoaded(this)" onerror="sheetError(this)"> <link rel="stylesheet" type="text/css" href="http://jsing.blog.hu/media/test.css" onload="sheetLoaded(this)" onerror="sheetError(this)"> </HEAD> <BODY> </BODY>
Ha a forráskódból nem derült volna ki: a kérdés az, hogy vajon működnek-e már így 2012-ben a stylesheet elemek onload illetve onerror eseménykezelői, és ha igen, akkor hogyan.
A tesztet szokásunk szerint kétféle browseren futtattuk le (lásd: "Notes", balra fent), magát a HTML oldalt egyszerűség kedvéért egy lokális könyvtárból betöltve. A kisérlet elvégzése előtt elkészítettünk egy test.css nevű file-t, amiből egy példányt feltöltöttünk a blog.hu-ra, egy másik példányt pedig local-test.css néven (biztos ami biztos alapon átneveztük, hogy ne lehessen keveredés) beraktunk a HTML oldalunk mellé.
A kísérlet kimenetele a kétféle browseren természetesen különböző lett:
Mozilla:
- Az oldal betöltésekor 3 messageboxot kaptunk - méghozzá egyszerre!!! Ez azt jelenti, hogy egyszerre 3 messagebox volt a képernyőn: az első megjelenése után azonnal megjelent a második, majd a harmadik - időnk sem volt elolvasni az elsőt, nemhogy becsukni, már jött is a második, majd a harmadik. Az üzenetekben szépen megkaptuk az elvárt információkat, miszerint a két létező css file betöltése sikerült, a harmadiké (local-missing.css) pedig nem. A window objektum onload eseményére akasztott eseménykezelőnk csak a három messagebox becsukása után jelentkezett be a maga kis üzenetével - feltehetően ekkor gondolta úgy a browser, hogy az oldal betöltése befejeződött, itt az ideje megcsengetnie a window.onload-ot...
- Ez a kimenetel a legmerészebb várakozásainkat is felülmúlta - sokáig az a hír járta ugyanis, hogy ilyen onload/onerror fícsört csak a másik browser biztosít...
A másik browser:
- Itt is 3 messageboxot kaptunk, de nem "egyszerre", hanem "egymás után": a második akkor jelent meg, amikor az elsőt bezártuk, a harmadik pedig a második bezárása után. A window objektum onload eseményére akasztott eseménykezelőnk pedig itt is a harmadik messagebox eltűnése aktivizálódott. Eltérés volt még, hogy a kiírt "href" ebben az esetben a href attribútum értékére korlátozódott, ellentétben a Mozillával, ami href attribútumként a komplett URL-t adta vissza. Ezzel együtt a másik browser működése végül is elfogadható lenne (szinte már KOMPATIBILITÁSról beszélhetünk), de:
- a másik browser mindhárom esetben a sheetLoaded() függvényünket hívta meg - azt állította tehát, hogy mindhárom css file betöltődött, még az is, amelyik nem létezik...
Jöhetett tehát a szokásos szívás a másik browserrel. A saját dokumentációjában az áll, hogy "An onerror event occurs when loading the object causes an error." Kiráj. Tehát szerintük a "file not found" az nem egy error. Brávó...
Nyilvánvalónak tűnik, hogy a sheetLoaded() függvény átírása a feladat: ha meghívódik, akkor nézze meg, hogy a másik browserről van-e szó - és ha igen, akkor valami módon el kell döntenie, hogy a css file tényleg betöltődött-e. Ahogy az az ilyen "browser-inkompatibilitási" esetekben lenni szokott, most is a 4ezer éves kínai szófordulat: "ez nem probléma, hanem lehetőség" adja kezünkbe a kulcsot. Rövid kutakodás után hamar meg is kaptuk a megoldást - az ide vezető út mellőzésével álljon itt a végeredmény:
function sheetLoaded(x) { if (x.styleSheet) { if (x.styleSheet.cssText == "") { sheetError(x); return; } } alert(x.href + "\nSheet is loaded."); }
Tisztában vagyunk vele, hogy a posztban bemutatott megoldás nem teljes, hiszen ez a verzió csak kétféle browsert tud kezelni. Ezzel együtt az az érzésünk, hogy megnyitottunk egy kaput, amin keresztül igen érdekes lehetőségek tárulnak elénk a cross-domain megoldások területén...
Maradjanak velünk, hamarosan jövünk a részletekkel...