2013-03-08 5 views
7

मैं इस साधारण समारोह जो वर्तमान डोम में स्क्रिप्ट लोड करता है है:लोड एक पटकथा के बाद एक और

function loadscripts (async) { 
    if(async === undefined) { 
     async = false; 
    } 

    var scripts = []; 
    var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js']; 

    for(var s in _scripts) { 
     scripts[s] = document.createElement('script'); 
     scripts[s].type = 'text/javascript'; 
     scripts[s].src = _scripts[s]; 
     scripts[s].async = async; 

     document.getElementsByTagName('head').appendChild(scripts[s]); 
    } 
} 

वे ठीक है और कोई त्रुटियों के बिना लोड किए गए हैं। मैं जानता हूँ कि जब स्क्रिप्ट प्रोग्राम के रूप में लोड हो रहा है ईवेंट हैंडलर्स देखते हैं:

  • onreadystatechange, और
  • ऑनलोड, आदि

अब मैं निम्न कार्य करना चाहते हैं करना चाहते हैं:

  • सरणी से पहली स्क्रिप्ट लोड करें, और जब ईवेंट हैंडलर अगले लोड को पूर्ण रूप से लोड करते हैं, और इतने पर (पुनरावर्ती)।

क्षमा करें, मैं अपने समारोह में onreadystatechange और onload घटनाओं प्रदान नहीं किया है।

+0

मैं आपको [headjs] (http://headjs.com) आज़माने का सुझाव देता हूं। कई स्क्रिप्ट प्रबंधित करना बहुत अच्छा है! –

+0

@MiguelRodrigues - सुझाव के लिए धन्यवाद, लेकिन मैं अपने स्वयं के हेडजेस को समान स्क्रिप्ट बना रहा हूं :) –

उत्तर

10

मैं इस तरह करना होगा:

LoadScripts(); 

function LoadScripts(async) 
{ 
    if(async === undefined) { 
     async = false; 
    } 
    var scripts = []; 
    var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js']; 

    if(async){ 
     LoadScriptsAsync(_scripts, scripts) 
    }else{ 
     LoadScriptsSync(_scripts,scripts) 
    } 
} 

// what you are looking for : 
function LoadScriptsSync (_scripts, scripts) { 

    var x = 0; 
    var loopArray = function(_scripts, scripts) { 
     // call itself 
     loadScript(_scripts[x], scripts[x], function(){ 
      // set x to next item 
      x++; 
      // any more items in array? 
      if(x < _scripts.length) { 
       loopArray(_scripts, scripts); 
      } 
     }); 
    } 
    loopArray(_scripts, scripts);  
} 

// async load as in your code 
function LoadScriptsAsync (_scripts, scripts){ 
    for(var i = 0;i < _scripts.length;i++) { 
     loadScript(_scripts[i], scripts[i], function(){}); 
    } 
} 

// load script function with callback to handle synchronicity 
function loadScript(src, script, callback){ 

    script = document.createElement('script'); 
    script.onerror = function() { 
     // handling error when loading script 
     alert('Error to handle') 
    } 
    script.onload = function(){ 
     console.log(src + ' loaded ') 
     callback(); 
    } 
    script.src = src; 
    document.getElementsByTagName('head')[0].appendChild(script); 
} 
0

इस प्रयास करें:

function loadscripts (async) { 
    if(async === undefined) { 
     async = false; 
    } 

    var scripts = []; 
    var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js']; 
    for(var s in _scripts) { 
     scripts[s] = document.createElement('script'); 
     scripts[s].type = 'text/javascript'; 
     scripts[s].src = _scripts[s]; 
     scripts[s].async = async; 
    } 
    var loadNextScript = function() { 
     var script = scripts.shift(); 
     var loaded = false; 
     document.getElementsByTagName('head').appendChild(script); 
     script.onload = script.onreadystatechange = function() { 
      var rs = this.readyState; 
      if (rs && rs != 'complete' && rs != 'loaded') return; 
      if (loaded) return; 
      loaded = true; 
      if (scripts.length) { 
       loadNextScript(); 
      } else { 
       // done 
      } 
     }; 
    }; 
    loadNextScript(); 
} 
+0

क्या यह "loadNextScript" फ़ंक्शन घोषणा "लूप के लिए" नहीं है? –

+0

@ZlatanO। नहीं, 'loadNextScript' को "असीमित रूप से" चलाने के लिए माना जाता है, जबकि' के लिए 'एकल, अवरुद्ध तरीके से चलता है। – Passerby

+0

आह .. इस समाधान से .. यह पहली बार 'स्क्रिप्ट' ऑब्जेक्ट को जोड़ता है, और फिर 'loadNextScript()' के साथ, उन्हें 'हेड' टैग में डालता है - दस्तावेज़ DOM में? –

0

आप इस तरह वादे के साथ यह कर सकता है।

// loads an individual script 
var loadScript = function (path) { 
    // generate promise 
    return new Promise(function (fulfill, reject) { 
     // create object 
     var script = document.createElement('script'); 

     // when it loads or the ready state changes 
     script.onload = script.onreadystatechange = function() { 
      // make sure it's finished, then fullfill the promise 
      if (!this.readyState || this.readyState == 'complete') fulfill(this); 
     }; 

     // begin loading it 
     script.src = path; 

     // add to head 
     document.getElementsByTagName('head')[0].appendChild(script); 
    }); 
}; 

// this is the one you want 
var loadScripts = function (scripts) { 
    return scripts.reduce(function (queue, path) { 
     // once the current item on the queue has loaded, load the next one 
     return queue.then(function() { 
      // individual script 
      return loadScript(path); 
     }); 
    }, Promise.resolve() /* this bit is so queue is always a promise */); 
}; 

उपयोग:

getScripts(["foo.js", "bar.js"]).then(function() { 
    // whatever you want to happen when it's all done 
}); 

हालांकि यह किसी भी त्रुटि हैंडलिंग नहीं करता है, तो आप को लागू करने के लिए यह है कि यदि आप इसकी जरूरत पड़ेगी।

1

दिए गए क्रम x, y, z में स्क्रिप्ट लोड करना था और क्योंकि मेरे पास केवल उनमें से कुछ थे। यह दृष्टिकोण मेरे लिए काम किया। इन्हें शरीर या सिर में लोड नहीं किया जा सका क्योंकि वे काफी बड़े हैं और मैं एक स्थिर लैंडिंग पृष्ठ का उपयोग कर रहा हूं।

document.addEventListener('DOMContentLoaded', function(event) { 
     // initial DOM loaded 
     var vendorJS = document.createElement('script'); 
     vendorJS.src = 'assets/vendor.js'; 

     var appJS = document.createElement('script'); 
     appJS.src = 'assets/application.js'; 

     var envJS = document.createElement('script'); 
     envJS.src = 'assets/env.js'; 

     document.body.appendChild(vendorJS); 

     vendorJS.onload = vendorJS.onreadystatechange = function() { 
      document.body.appendChild(appJS); 

      appJS.onload = appJS.onreadystatechange = function() { 
       document.body.appendChild(envJS); 
      }; 
     }; 
}); 
संबंधित मुद्दे