Advertisement
Guest User

JS Loader

a guest
Oct 17th, 2010
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Javascript loaded using Loader can arrive after DOMContentLoaded has occured.
  2. // Remember if DOMContentLoaded has happened, so loaded JS knows if it's safe to execute.
  3. document.addEventListener && document.addEventListener( "DOMContentLoaded", function() { Loader.documentReady = true; }, false );
  4.  
  5. /**
  6.  * Load files in parallel.
  7.  * Each call to 'script' adds a batch. Batches are loaded sequentially, while files in a batch are loaded in parallel.
  8.  *
  9.  * Public functions:
  10.  * - script
  11.  */
  12. Loader = {
  13.     batches: [],
  14.     documentReady: false,
  15.     isLoading: false,
  16.    
  17.     /**
  18.      * Add an array of script files that can be loaded in parallel (don't have dependencies amongst each other).
  19.      *
  20.      * @param files{Array}: an array of urls.
  21.      * @param options{object}: a map of options.
  22.      *          Required properties: none.
  23.      *          Optional properties:
  24.      *              - complete{Function}: function called after a batch of loads has completed
  25.      *              - timeout{Number}: set a timeout for load requests
  26.      *              - attributes{Object}: a bag of attribute names/values that should be applied to created script tags.
  27.      */
  28.     script: function( files, options ) {
  29.         options = options || {};
  30.         options.files = files;
  31.         options.element = 'script';
  32.        
  33.         options.attributes = options.attributes || {};
  34.         options.attributes.type = 'text/javascript';
  35.        
  36.         // add files to batches, start processing a batch if we currently aren't
  37.         if ( files.length ) {
  38.             this.batches.push( options );
  39.            
  40.             if ( !this.isLoading )
  41.                 this.loadBatch( this.batches.shift() );
  42.         }
  43.     },
  44.    
  45.     /**
  46.      * Start loading the next batch of files from the 'batches' array.
  47.      */
  48.     loadBatch: function( options ) {
  49.         var dit = this;
  50.         var head = document.getElementsByTagName( 'head' )[0];
  51.         var loading = [];
  52.         this.isLoading = true;
  53.        
  54.         // Add each file in options.files to the head
  55.         for ( var i = 0; i < options.files.length; i++ ) {
  56.             var js = document.createElement( options.element );
  57.             js.src = options.files[ i ];
  58.            
  59.             for ( var j in options.attributes )
  60.                 js[ j ] = options.attributes[ j ];
  61.        
  62.             new this.l( js, options.timeout || 10000, callback );
  63.             loading.push( js );
  64.             head.appendChild( js );
  65.         }
  66.        
  67.         // callback used by 'l' after success or timeout
  68.         function callback( elem ) {
  69.             // remove 'elem' from 'loading'
  70.             for ( var i = 0; i < loading.length; i++ ) {
  71.                 if ( elem === loading[ i ] ) {
  72.                     loading.splice( i, 1 );
  73.                     //console.log( 'loaded %s', elem.src );
  74.                     break;
  75.                 }
  76.             }
  77.            
  78.             // fire success callback, start next batch if available
  79.             if ( !loading.length ) {
  80.                 if ( typeof( options.complete ) === 'function' )
  81.                     window.setTimeout( function() { options.complete(); }, 10 );
  82.                
  83.                 // if there are more batches, load the next one
  84.                 if ( dit.batches.length ) {
  85.                     window.setTimeout( function() { dit.loadBatch( dit.batches.shift() ); }, 10 );
  86.                 }
  87.                 else
  88.                     dit.isLoading = false;
  89.             }
  90.         }
  91.     },
  92.    
  93.     l: function( elem, timeout, callback ) {
  94.         elem.onreadystatechange = readyStateChange;
  95.         elem.onerror = elem.onload = completed;
  96.        
  97.         var t = setTimeout( completed, timeout );
  98.        
  99.         // Triggered by load/error/readystate. This = the DOMElement.
  100.         function completed() {
  101.             clearTimeout( t );
  102.             elem.onreadystatechange = elem.onload = elem.onerror = null;
  103.             callback( elem );
  104.         };
  105.        
  106.         function readyStateChange() {
  107.             if ( elem.readyState == "loaded" || elem.readyState == "complete" ) elem.onload();
  108.         };
  109.        
  110.         return this;
  111.     }
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement