document.createElement('script')... 使用一个回调添加两个脚本

发布于 2024-08-14 03:43:00 字数 384 浏览 4 评论 0原文

我需要添加原型,然后添加 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 个回调方法的愚蠢链)。有想法吗?

I need to add prototype and then add scriptaculous and get a callback when they are both done loading. I am currently loading prototype like so:

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

I could do this by chaining the callbacks, but that seems like poor practice ( I don't want a silly chain of 20 callback methods when I need to load more scripts). Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

朮生 2024-08-21 03:43:00

我建议你使用一些小型装载机,它可以链接并为你做一些事情。例如,像这样:

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

希望这会有所帮助

I propose you to use some small loader which will chain and do stuff for you. For example like this one:

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

This script should help you to build the script tags and call your callback when all files are loaded. Invoke is pretty easy:

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

Hope this will help

谎言月老 2024-08-21 03:43:00

由于 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 中的解决方案,当出现无法解释的问题时,这种情况太常见了。

Because of a bug in Internet Explorer the recursive loader program from nemisj is not working correct in IE. Can be solved by setting a delay on the recursive call like:


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

This small hack does it, and often is the solution in IE, when an unexplainable problem occurs, which is too often.

眼中杀气 2024-08-21 03:43:00

由于 scriptaculous 需要原型,因此您必须使用任何加载这些脚本的方法来链接侦听器。

有各种脚本加载器可用于尽可能快地并行加载脚本,例如 LABjs,但没有一个有帮助在这种情况下。

如果您最终要加载 10-20 个脚本,我建议您使用 等工具预先组合这些脚本组合器

Since scriptaculous requires prototype, you will have to chain the listeners, with whatever method you use to load these scripts.

There are various script loaders available to load scripts in parallel, as fast as possible, e.g. LABjs, but none is going to help much in this scenario.

If you end up having 10-20 scripts to load, I would recommend combining the scripts beforehand, using a tool such as a Combiner.

一人独醉 2024-08-21 03:43:00

您可以承诺 脚本的 .onload 和 .onerror 回调,然后使用 Promise.all 等待所有 Promise 解析,然后再继续执行依赖于这些脚本的操作。

这是一个例子:

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/[email protected]/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))
;

You can promisify the script's .onload and .onerror callbacks, then use Promise.all to wait for all of the promises to resolve before continuing with execution that is dependent on these scripts.

Here's an example:

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/[email protected]/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))
;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文