【问题标题】:Dynamic, cross-browser script loading动态的跨浏览器脚本加载
【发布时间】:2011-07-17 16:40:58
【问题描述】:

我知道 IE 没有针对 <script> 元素的 load 事件 — 有没有办法可靠地弥补这一点?

我看到了一些关于事情的讨论(例如,requestState == "complete"),但没有什么非常可验证的。


这是为了在脚本加载完成后调用代码,这样我就不必使用 AJAX 来加载新的源(从而消除跨域 AJAX 的问题)。

【问题讨论】:

  • 您能否在您正在加载的脚本中放置一个函数调用,该函数调用将在评估脚本时运行,这将成为您的完成回调?

标签: javascript internet-explorer asynchronous cross-browser


【解决方案1】:

您可以使用像head.js 这样的脚本加载器。它有自己的加载回调,它也会减少加载时间。


来自headjs 代码:(稍作修改以更便携)

function scriptTag(src, callback) {

    var s = document.createElement('script');
    s.type = 'text/' + (src.type || 'javascript');
    s.src = src.src || src;
    s.async = false;

    s.onreadystatechange = s.onload = function () {

        var state = s.readyState;

        if (!callback.done && (!state || /loaded|complete/.test(state))) {
            callback.done = true;
            callback();
        }
    };

    // use body if available. more safe in IE
    (document.body || head).appendChild(s);
}

【讨论】:

  • 恐怕我不明白一个库如何减少由网络延迟引起的加载时间:)
  • 浏览器按顺序加载“
  • 你怎么看?如果您让它们同时加载而不是一个接一个地加载,所有脚本将加载得更快。可能是我解释不好,headjs 网站上有很好的描述。
  • 此方法允许您控制并行和串行加载。它还可以让您知道它们何时完成。这比只从上到下同步加载的浏览器要好,它会保留下面的内容。
  • 如果一个脚本中的代码依赖于另一个脚本中的代码,这表明您可能希望尽可能将一些脚本连接在一起。
【解决方案2】:

我想补充一点,如果你不支持 IE7 及以下,你不需要onreadystatechange 的东西。来源:quircksmode.org

原始答案中的简化且工作代码:

function loadScript(src, callback) {    
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.src = src;
    s.async = false;
    if(callback) {
        s.onload = callback;     
    }
    document.body.appendChild(s);
}

【讨论】:

    【解决方案3】:

    这只是 ilia 答案的延伸。我这样使用 scriptTag:效果很好:

        // these 3 scripts load serially.
    
        scriptTag(boot_config.DEPENDENCIES.jquery,function(){
            // jquery ready - set a flag
            scriptTag(boot_config.DEPENDENCIES.jqueryui,function(){
                // jqueryui ready - set a flag
                scriptTag(boot_config.DEPENDENCIES.your_app,function(){
                    // your_app is ready! - set a flag
                });
            });
        });
    
        // these 2 scripts load in paralell to the group above
    
        scriptTag(boot_config.EXTERNALS.crypto,function(){
            // crypto ready - set a flag
        });
    
        scriptTag(boot_config.EXTERNALS.cropper,function(){
            // cropper ready - set a flag
        });
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多