Kam dát javascripty komponenty: krásné řešení
- danik
- Člen | 56
Helou,
řešil jsem takhle jednou otázku.. mám ne úplně málo JS knihoven a
kvůli rychlosti je chci vkládat až na konec <body>
. To ale
znamená, že všechen ostatní kód pohledů se zpracovává předtím, než se
načtou knihovny, a tím pádem knihovny v tomhle kódu nejsou k dispozici…
tak jsem si vymyslel block „scripts“, kterej je na konci body
až za načítáním knihoven a je obalen snippetem. Neat!
Ale tak nějak málo neat. Protože pak jsem se konečně naučil používat komponenty a rázem jsem se octnul v loji. Protože zevnitř z komponenty už tohle zase nešlo.
A tak jsem okopíroval Google. Přesněji řečeno Google Analytics.
Pamatujete, jak v GA kódu bejvalo takovýto ga.push(...)
..?
A tak vzniknul _stack.
_stack
je globální javascriptové pole. Do HTML hlavičky se
vloží jednořádkovej inline javascript, kterej říká, že
var _stack = [];
. To je vše.
Inline skripty, ať už jsou potom kdekoliv (šablona view presenteru, šablona komponenty, …) všechny obalím do closure, kterou pushnu do pole _stack:
<script>
/* <![CDATA[ */
_stack.push(function() {
// můj kód :-)
});
/* ]]> */
</script>
Pak načítám knihovny a jako úplně poslední načtu mikroknihovnu
stack.js
(viz následující post), která v zásadě dělá jen
to, že projede celé pole _stack a všechny funkce v něm spustí. Když je
s tím hotová, přepíše metodu push()
tak, že tato místo
přidání nových prvků tyto spustí rovnou.
To znamená, že aniž bych jakkoliv zatěžoval server-side, mám vždy zaručené, že jakýkoliv client-side JS kód se spustí až po načtení všech potřebných knihoven..
CC-BY-SA :-)
Editoval danik (18. 11. 2013 22:22)
- danik
- Člen | 56
<script>
// stack.js
(function(stack, context) {
var exec = function(f) {
if (typeof f === 'function') {
context.invoke(f);
} else {
context.invoke.apply(context, f);
}
};
while (stack.length) {
exec(stack.shift());
}
stack.push = function() {
for (var i = 0; i < arguments.length; i++) {
exec(arguments[i]);
}
};
})(_stack || [], _context);
</script>
A totéž v minifikované verzi (225 znaků!):
<script>
// stack.min.js
(function(s,c,e){e=function(f){if(typeof f==='function'){c.invoke(f);}else{c.invoke.apply(c,f);}};while(s.length){e(s.shift());}s.push=function(){for(var i=0;i<arguments.length;i++){e(arguments[i]);}};})(_stack||[],_context);
</script>
A co že je to ten context?? To be continued ;-)
Editoval danik (18. 11. 2013 22:54)
- danik
- Člen | 56
Tak _context nam smazali.. bohuzel. Prej to neni dost Nette. Zrovna jsem chtel uploadovat aktualizovanou verzi ktera ma vyreseny ty TODOcka.. takze umi CORS, chtre seskupovat scriptovy nacitani a jeste par dalsich veci ktery jsem domyslel po ceste.. ale my jsme si rekli ne :-)
Editoval danik (19. 11. 2013 17:19)