14

プロトタイプを追加してからscriptaculousを追加し、両方の読み込みが完了したらコールバックを取得する必要があります。私は現在、次のようにプロトタイプをロードしています。

var script = document.createElement("script");
script.src = "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js";
script.onload = script.onreadystatechange = callback;
document.body.appendChild( script );

コールバックをチェーンすることでこれを行うことはできますが、それは悪い習慣のようです(さらにスクリプトをロードする必要がある場合、20のコールバックメソッドのばかげたチェーンは必要ありません)。アイデア?

4

4 に答える 4

45

私はあなたにチェーンしてあなたのために何かをする小さなローダーを使うことを提案します。たとえば、次のようになります。

function loadScripts(array,callback){
    var loader = function(src,handler){
        var script = document.createElement("script");
        script.src = src;
        script.onload = script.onreadystatechange = function(){
            script.onreadystatechange = script.onload = null;
            handler();
        }
        var head = document.getElementsByTagName("head")[0];
        (head || document.body).appendChild( script );
    };
    (function run(){
        if(array.length!=0){
            loader(array.shift(), run);
        }else{
            callback && callback();
        }
    })();
}

このスクリプトは、スクリプトタグを作成し、すべてのファイルがロードされたときにコールバックを呼び出すのに役立ちます。呼び出しは非常に簡単です。

loadScripts([
   "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js",
   "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"
],function(){
    alert('All things are loaded');
});

これがお役に立てば幸いです

于 2009-12-08T13:57:33.047 に答える
2

Internet Explorerのバグが原因で、nemisjの再帰ローダープログラムがIEで正しく機能していません。次のように再帰呼び出しに遅延を設定することで解決できます。


function loadScripts(array,callback){  
    var loader = function(src,handler){  
        var script = document.createElement("script");  
        script.src = src;  
        script.onload = script.onreadystatechange = function(){  
          script.onreadystatechange = script.onload = null;  
          if(/MSIE ([6-9]+\.\d+);/.test(navigator.userAgent))window.setTimeout(function(){handler();},8,this);  
          else handler();  
        }  
        var head = document.getElementsByTagName("head")[0];  
        (head || document.body).appendChild( script );  
    };  
    (function(){  
        if(array.length!=0){  
                loader(array.shift(),arguments.callee);  
        }else{  
                callback && callback();  
        }  
    })();  
}  

この小さなハックはそれを行い、説明のつかない問題が発生した場合のIEの解決策であることが多く、これはあまりにも頻繁です。

于 2011-04-28T03:15:08.640 に答える
1

scriptaculousにはプロトタイプが必要なため、これらのスクリプトをロードするために使用する方法に関係なく、リスナーをチェーンする必要があります。

LABjsなど、スクリプトを可能な限り高速に並列にロードするために使用できるさまざまなスクリプトローダーがありますが、このシナリオではあまり役に立ちません。

10〜20個のスクリプトをロードすることになった場合は、Combinerなどのツールを使用して、事前にスクリプトを結合することをお勧めします。

于 2009-12-08T14:12:58.997 に答える
0

スクリプト .onload.onerrorコールバックをPromise.all約束してから、これらのスクリプトに依存する実行を続行する前に、すべての約束が解決されるのを待つために使用できます。

次に例を示します。

const loadScript = url => 
  new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = url;
    script.onload = resolve;
    script.onerror = e => 
      reject(Error(`${url} failed to load`))
    ;
    document.head.appendChild(script);
  })
;

const scriptURLs = [
  "https://unpkg.com/htm",
  "https://unpkg.com/axios@0.21.0/dist/axios.min.js",
  "https://cdnjs.cloudflare.com/ajax/libs/d3/6.3.1/d3.min.js",
  // ...
];

Promise.all(scriptURLs.map(loadScript))
  .then(async () => {
    /* Use your scripts here */
    console.log("proving scripts loaded:");
    axios.get("http://jsonplaceholder.typicode.com/users");
    console.log(d3.csvParse("a,b\n3,4\n5,6"));
    const html = htm.bind((t, p, ...c) => ({t, p, c}));
    console.log(html`<h1 id=hello>Hello world!</h1>`);
  })
  .catch(err => console.error(err))
;

于 2020-12-16T23:52:22.270 に答える