Tak mel bych tu zase jednu novinku, zatim spis takovy prototyp, kteremu jeste musim dat trochu ucelenejsi formu, ale kdyby si s tim chtel nekdo hrat, tak aspon myslenka.
Predesilam, ze pokud jde o user scripty, tak to bude fungovat jenom v Opere, GreaseMonkey to principialne neumi (mnohokrat se to v konferenci resilo, problem je v tom, ze to proste nejde napasovat na Gecko jako takove). Ale ta idea se da pouzit i v ramci normalnich javascriptu na nejakych vlastnich strankach, tam to bude fungovat vsude
Uz dlouho jsem premyslel, ze by bylo obcas vhodne moct provest nejakou javascriptovou iniciaci (zhruba) presne ve vhodny moment - obvykle se iniciuje, kdyz nastane load na dokumentu, jenze to na velkych dokumentech a/nebo pomalych linkach dlouho trva, navic to obvykle jeste "vylepsi" vsemozne toplisty a reklamni bannery, ktere jsou vecne pretizene, takze stranka uz je skoro cela nactena, lec udalost load ne a ne nastat. Tudiz jsem napsal funkci, ktera bere dva parametry - prvnim je podminka, ktera se nad dokumentem testuje, druhym je kod, ktery se vykona. Funguje to tak, ze dokud nenastane zminovana podminka, tak se tahle funkce s urcitou prodlevou rekurzivne vola (ta prodleva je tam proto, aby zase procesor moh delat i neco jinyho), a az podminka nastane, zavola se pozadovany kod. Priklad - budu chtit javascriptem cosi zmenit na nejakem divu presne v momente, kdy uz ten div vubec bude existovat (prohlizec stahne dostatek stranky na to, aby si ten div uz zaradil do vytvareneho stromu dokumentu) - tak proste (rekneme, ze ten div ma nejake id, podle ktereho ho najdu) tak dlouho testuju, zda uz ten div existuje, dokud to nenastane, a az ano, provedu modifikaci. Tudiz to nastane v ten v podstate nejdrivejsi okamzik, kdy je mozne, aby to nastalo. Samozrejme je dobre davat pozor na to, abychom neskoncili v nekonecne rekurzi, takze je typicky na miste pridat si omezeni, ze nastane-li nacteni celeho dokumentu a pritom jeste furt nenastala "nase" podminka, tak cely mechanismus skonci.
Zminovana funkce vypada asi takto (plus nejaky dalsi nutny obsluzny kod):
function initWithCondition(condition, whatToDo) {
if (window.loaded || !eval(condition)) {
eval(whatToDo);
return;
}
if (window.initWithConditionInterval != undefined) setTimeout(initWithCondition, window.initWithConditionInterval, condition, whatToDo);
}
window.addEventListener("load", function() { window.loaded = true; }, false);
window.initWithConditionInterval = 100;
Nevim takhle zpameti, jestli se da nejak sikovne zjistit, jestli uz byl document nacten (dost mozna jo), tak tady pro jistotu odchytavam prave udalost load a pokud nastane, tak si na window ulozim, ze tomu tak bylo (predposledni radek). Posledni radek nastavuje prodlevu na 100 ms (lze upravit dle libosti). Funkce samotna pak pokud byl dokument nacten nebo prestala platit podminka vykona urceny kod a skonci (jinak sama sebe zavola s urcenou prodlevou). K tomu opet nejake podminky - mozna by bylo nekdy spise vhodnejsi, kdyz nastal load, skoncit bez vykonani urceneho kodu, to uz si musite sami rozmyslet. Stejne tak se mozna nekomu hure bude zadavat podminka v tomto tvaru a lepe by se zadavala negovana (znamy problem do while versus repeat until), uprava je opet evidentni. Navic by asi stalo za to volani evalu obalit nejakym try-catchem a vubec to udelat trochu robustnejsi vuci chybam, to nekdy v pozdejsich verzich.
Konkretni ukazka pouziti zavolani teto funkce:
initWithCondition("document.documentElement.id == \"\"", "setHTMLId()");
Co to udela - otestuje, testuje, jak je na tom korenovy element dokumentu s atributem id. Dokud je id prazdne, bude volat funkci setHTMLId().
Cimz se malym oslim mustkem dostavam k tomu, ceho jsem tim chtel dosahnout predevsim (byt je mechanismus, jak vidno, znacne obecnejsi). Funkce setHTMLId() totiz vypada takto:
function setHTMLId() {
var html = document.documentElement;
if (html == undefined) return;
if (html.id == "") {
var host = location.host;
var hostSplitted = host.split(".");
var id = "";
for (i = 0; i < hostSplitted.length; i++) {
if (i > 0) id += "-";
id += hostSplitted[i];
}
html.id = id;
}
}
Opet to neni moc testovano, ale funkce je pomerne trivialni - pokud element html ma nastaveno id, nedela to nic, pokud nema, vezme to domenu adresy (treba www.lopuch.cz), rozseka podle tecek a spoji pomlckama (kdyz ted nad tim premyslim, tak jsem to mozna mel psat trochu strizlivejsi a proste jenom v tom retezci zamenit tecky za pomlcky, ale to uz je ted jedno), cili vyrobi neco jako www-lopuch-cz a tohle to priradi atributu id.
Pokud z tohohle clovek vyrobi user script a necha ho aplikovat na uplne vsechny weby, zajisti tim, ze kazdy web, ktery navstivi, bude mit rozumne nastaveno id u elementu html.
No a pokud jeste furt neni jasne, kam mirim, tak timto lze delat velmi ucelna a cilena uzivatelska CSS - proste upravovat si CSS jednotlivych webu (treba kdyz pouzivaji nevhodne fonty/barvy/cokoliv). Jak toho pak docilit je uz zrejme.
Posledni poznamka na zaver objasnujici, proc si s tim davat tolik prace a nenasetovat to id proste opravdu az tehdy, kdy nastane na strance load. Trochu uz jsem to zminil - ten muze nekdy nastat velmi pozde, treba az tehdy, kdy vlastne stranku zase clovek opousti, takze by se to CSS vubec nestihlo pouzit. Druhy duvod, proc je to az pri naloadovani nevhodne, je ten, ze je-li stranka velmi dlouha, procesor se pri loadu nemalo zapoti - vim, ze kdyz jsem takhle Lapiduchu prave menil font, tak se tim znacne zmenilo cele formatovani a u klubu s nactenou stovkou prispevkou klidne mohlo vterinu dve trvat, nez se to preformatovalo. |