2010-11-22 3 views
0

다음 목록의 각 항목에는 스크립트 파일 url과 콜백 함수가 있습니다.이 목록을 반복 실행하고 각 스크립트를로드 한 다음 실행합니다. 현재 콜백 실행이 완료되지 않으면 다음 항목으로 이동 콜백 기능, 하지 .. 가능하면 내가 자동으로 수행 할 수있는 방법순차 콜백으로 자바 스크립트 파일을 자동으로로드하기


var data = { 
    scripts: [ 
     { 
      file : 'some-script.js', 
      callback: function() { 
       // do some code here 
      }, 
     }, 
     { 
      file : 'another-script.js', 
      callback: function() { 
       // do some code here 
      }, 
     }, 
     ... 
    ] 
}; 

?

+1

** 오프 주제 ** : 개체 리터럴의 마지막 재산 후 그 매달려 쉼표, 일부 브라우저에서 당신을 위해 문제 세부 사항을하려고 : http://blog.niftysnippets.org/2010 /09/literal-improvement.html –

+0

나는로드 할 스크립트보다 많을 것임을 나타 내기 위해이 쉼표를 넣었습니다. 어쨌든 주석에 대해서도 포스트에 감사하지만 타임 아웃을 배치하는 것이 좋다고는 생각하지 않습니다. 아이디어, 보편적으로 어떤 콜백 코드에 상관없이 작동하는 무언가를 만들 계획입니다. –

답변

2

(외부 스크립트를로드하는 데 JSONP을 사용한다고 가정합니다.) 문제는 이러한 스크립트가 동시에로드되지 않는다는 것입니다.

다음은 연관된 스크립트가로드되는 즉시 콜백 함수를 호출하는 코드입니다.

function include_js(url, callback) { // http://www.nczonline.net 
     var script = document.createElement("script"); 
     script.type = "text/javascript"; 

     if (script.readyState) { //IE 
      script.onreadystatechange = function(){ 
       if (script.readyState == "loaded" || script.readyState == "complete"){ 
        script.onreadystatechange = null; 
        callback(); 
       } 
      }; 
     } else { //Others 
      script.onload = function(){ 
       callback(); 
      }; 
     } 
     script.src = url; 
     document.getElementsByTagName("head")[0].appendChild(script); 
    } 

//Edit 

    for (var i = 0; i < data.scripts.length; i++) { 
     include_js(data.scripts[i].file, data.scripts[i].callback); 
    } 
+0

완벽하게 작동했습니다! –

+0

여기서 익숙한 함수가 코드를 실행하기 전까지는 for 루프에서 다음 요소로 이동하지 않을 것입니다, 맞습니까? –

1

각 스크립트에서 테스트 할 수있는 심볼이 있거나로드가 완료되면 각 스크립트가 함수 호출을 실행할 수 있는지 여부는 일 수 있습니다. 스크립트를로드

내가 확신 당신이 알고, 쉽게 : (. 당신은 사람들이 대신 head에 추가 볼 수 있습니다; 중요하지 않으며, body 쉽게 찾을 수)

var script = document.createElement('script'); 
script.src = /* ... the source path ... */; 
document.body.appendChild(script); 

그러나 어려운 부분은 다운로드 및 실행 시점을 알고 있습니다. 스크립트를 통해 정의 된 새로운 전역 심볼이 정의되었는지 또는 로딩이 완료되면 스크립트가 적극적으로 다시 호출 하는지를 폴링하여 확인할 수 있습니다 (a'la JSONP).

어떤 방법 으로든 기호를 찾거나 콜백을 받으면 다음 스크립트를로드하는 단계로 넘어갑니다.

여기에 글로벌 기호합니다 (window 객체의 속성을) 발견에 근거하여 그 일의 빠른 - 및 - 더러운 스케치입니다 :

// The scripts to load 
var scriptList = { 
    scripts: [ 
     { 
      file : 'some-script.js', 
      callback: function() { 
       // do some code here 
      }, 
      symbol : "someSymbol", 
      timeout : 30000 // We know this one is slow, give it 30 seconds 
     }, 
     { 
      file : 'another-script.js', 
      callback: function() { 
       // do some code here 
      }, 
      symbol : "anotherSymbol" 
     }, 
     // ... 
    ] 
}; 

// Triggering the load 
loadScripts(scriptList); 

// Library routines to do the load 
function loadScripts(list) 
{ 
    var index, timeout; 

    // Start with the first one (loadNextScript starts with an increment) 
    index = -1; 
    loadNextScript(); 

    // This function loads the next script in the list; if there are no 
    // more, it simply returns 
    function loadNextScript() 
    { 
     var script; 

     // Are there more? 
     ++index; 
     if (index < list.length) 
     { 
      // Yes, append a `script` element 
      script = document.createElement('script'); 
      script.src = list.file; 
      document.body.appendChild(script); 

      // Determine when to time out 
      timeout = new Date() + (list[index].timeout || 20000); // Time out in Xms, default 20 seconds 

      // Start polling 
      setTimeout(pollForScript, 0); // Async, but almost immediately (4-10ms on most browsers) 
     } 
    } 

    // This function polls to see if the current script has loaded yet by 
    // checking for a global symbol it defines. 
    function pollForScript() 
    { 
     var result; 

     // Has it been too long? 
     if (new Date() > timeout) 
     { 
      // Yes 
      result = "timeout"; 
     } 
     else 
     { 
      // Has the symbol been defined? 
      if (typeof window[list[index].symbol] !== "undefined") 
      { 
       // Yes 
       result = "loaded"; 
      } 
      else 
      { 
       // Nope, keep waiting 
       setTimeout(pollForScript, 250); // Check every quarter-second 
      } 
     } 

     // Did we get a result? 
     if (result) 
     { 
      // Yes, do the callback telling it of the result 
      try { 
       list[index].callback(result); 
      } 
      catch (e) { 
      } 

      // Load the next script 
      loadNextScript(); 
     } 
    } 
} 
0

콜백이 loadTheNextScriptInList 또는 어떤 함수를 호출하자. onLoad 이벤트에 익명 함수를 추가하여 자동으로이 작업을 수행 할 수 있습니다. 이 익명 함수는 먼저 목록에 설정된 콜백을 호출 한 다음 loadTheNextScriptInList 함수를 호출해야합니다.

0

이것은 내가 작성하고 치료하지 않은 것일 뿐이지 만 재귀적인 방식으로 처리해야합니다. 희망이 도움이 :

var data = { 
    scripts: [ 
     { 
      file : 'some-script.js', 
      callback: function() { 
       // do some code here 
      }, 
     }, 
     { 
      file : 'another-script.js', 
      callback: function() { 
       // do some code here 
      }, 
     }, 
     ... 
    ] 
}; 


$(document).ready(function() { 

    if(data.scripts.length > 0) { 
     scriptLoader(0); 
    } 

}); 

function scriptLoader(i) { 


    var currScript = data.scripts[i]; 


    $.getScript(currScript.file, function() { 

     // execute your callback 
     currScript.callback(); 

     // load next script 
     if(i < data.scripts.length) { 
     scriptLoader(i++); 
     } 

    }); 

} 

아, 그리고 이것은 JQuery 자바 스크립트 프레임 워크를 사용합니다. 단지 FYI입니다.

+0

그냥 내 생각에 이것은 jquery를 동적으로로드하려는 시도가 아니며 순차적으로 종속 파일이라고 언급했습니다. 그렇지 않으면 간단하게 보입니다.: P – purefusion

관련 문제