views:

146

answers:

2

I'm trying to implement an assets/dependency loader that i've found from an old article at 24Ways.org. most of you might be familiar with it. it's from this article by Christian Heilmann:

http://24ways.org/2007/keeping-javascript-dependencies-at-bay

i've modified the script to load CSS files as well. and it's now quite close to what i want. but i still need to do some checking to see wether an asset have been completely loaded or not.

just wondering if you guys have any ideas :)

here's what my script currently looked like:

var assetLoader = {
  assets: {
    products: {
      js: 'products.js',
      css: 'products.css',
      loaded: false
    },
    articles: {
      js: 'articles.js',
      css: 'articles.css',
      loaded: false
    },

    [...]

    cycle: {
      js: 'jquery.cycle.min.js',
      loaded: false
    },
    swfobject: {
      js: 'jquery.swfobject.min.js',
      loaded: false
    }
  },
  add: function(asset) {
    var comp = assetLoader.assets[asset];
    var path = '/path/to/assets/';

    if (comp && comp.loaded == false) {
      if (comp.js) {
        // load js
        var js = document.createElement('script');
        js.src = path + 'js/' + comp.js;
        js.type = 'text/javascript';
        js.charset = 'utf-8';
        // append to document
        document.getElementsByTagName('body')[0].appendChild(js);
      }
      if (comp.css) {
        // load css
        var css = document.createElement('link');
        css.rel = 'stylesheet';
        css.href = path + 'css/' + comp.css;
        css.type = 'text/css';
        css.media = 'screen, projection';
        css.charset = 'utf-8';
        // append to document
        document.getElementsByTagName('head')[0].appendChild(css);
      }
    }
  },
  check: function(asset) {
    assetLoader.assets[asset].loaded = true;
  }
}

Christian explains this method in his article in great detail. I don't want to confuse you guys anymore with my bad english :P

and here's an example of how i run the script:

...

// load jquery cycle plugin
if (page=='tvc' || page=='products') {
  if (!assetLoader.assets.cycle.loaded) {
    assetLoader.add('cycle');
  }
}
// load products page assets
if (!assetLoader.assets.products.loaded) {
  assetLoader.add('products');
}

...

this kind of approach is very problematic though. coz assets loads asynchronously, which means some of the code inside products.js that depends on jquery.cycle.js might continue running before jquery.cycle.js is even loaded resulting in errors.

while i'm quite aware that scripts can be attached with an onload event, i'm just not really sure how to implement it to my script. anyone care to help me? please... :P

A: 

Why reinvent the wheel? Dojo has this built in with dojo.require and jQuery has the Include plugin.

As for CSS, minify and load it upfront as you normally would. This keeps things simpler and it's unlikely to be too costly load-time wise.

Justin Johnson
you're probably right about the CSS, the total size of them combined and gzipped is around 30 KB. maybe i'm over optimizing with this.i'll look into those reference u guys found. thx a lot.i've also found a thread here that might be useful. found some interesting links there :)http://stackoverflow.com/questions/2043799/javascriptlazy-loading-and-dependency-resolution
br4inwash3r
A: 

For js files you can use $.getScript, it provides a callback option so you can chain the loading, i.e:

$.getScript('jquery.cycle.js',function(){ 
    $.getScript('products.js'); 
});
Master Morality