2013-03-08 5 views
7

나는 현재 DOM에을 스크립트를로드이 간단한 기능을 가지고 : 그들은 잘없고 오류없이로드로드 한 스크립트 후 다른

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

  • 온로드 : 나는 프로그래밍 스크립트를로드 할 때 이벤트 핸들러가 알고
    • 배열에서 첫 번째 스크립트를로드하고 이벤트 처리기가 완료되면 다음 스크립트를로드하십시오. (재귀 적으로).

    죄송합니다, 내 함수에서 onreadystatechangeonload 이벤트를 제공하지 않았습니다.

+0

[headjs] (http://headjs.com)을 사용해 보시기 바랍니다. 여러 스크립트를 관리하는 것이 좋습니다! –

+0

@MiguelRodrigues - 제안 주셔서 감사합니다,하지만 난 내 자신의 headjs 비슷한 스크립트를 만들고있어 :) –

답변

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

"for 루프"아래에 있어야 할이 "loadNextScript"함수 선언이 아닌가요? –

+0

@ ZlatanO. 아니요,'loadNextScript'는 "비동기 적으로"실행될 것입니다. 반면에 for는 하나의 차단 방식으로 실행됩니다. – Passerby

+0

aha ..이 솔루션은 .. 먼저'scripts' 객체를 추가 한 다음'loadNextScript()'를 사용하여 문서 DOM에'head' 태그를 넣습니다. –

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); 
      }; 
     }; 
});