动态加载JavaScript文件

你如何可靠和动态地加载JavaScript文件? 这可以用来实现一个模块或组件,当“初始化”组件时,会根据需要动态加载所有需要的JavaScript库脚本。

使用该组件的客户端不需要加载实现此组件的所有库脚本文件(并手动将<script>标记插入到其网页中) - 只是“主要”组件脚本文件。

主流JavaScript库如何完成这个(Prototype,jQuery等)? 这些工具是否将多个JavaScript文件合并到脚本文件的单个可再发行版本“构建版本”中? 或者他们是否动态加载辅助“图书馆”脚本?

除了这个问题: 在加载动态包含的JavaScript文件后,是否有办法处理事件? Prototype具有document.observe用于文档范围的事件。 例:

document.observe("dom:loaded", function() {
  // initially hide all containers for tab content
  $$('div.tabcontent').invoke('hide');
});

脚本元素的可用事件是什么?


您可以编写动态脚本标记(使用Prototype):

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

这里的问题是,我们不知道外部脚本文件何时被完全加载。

我们经常希望我们的代码在下一行,并且喜欢写下如下内容:

if (iNeedSomeMore) {
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
    myFancyMethod(); // cool, no need for callbacks!
}

有一种聪明的方式可以在不需要回调的情况下注入脚本依赖关系。 您只需通过同步AJAX请求来提取脚本并在全局级别上评估脚本。

如果您使用Prototype,则Script.load方法如下所示:

var Script = {
    _loadedScripts: [],
    include: function(script) {
        // include script only once
        if (this._loadedScripts.include(script)) {
            return false;
        }
        // request file synchronous
        var code = new Ajax.Request(script, {
            asynchronous: false,
            method: "GET",
            evalJS: false,
            evalJSON: false
        }).transport.responseText;
        // eval code on global level
        if (Prototype.Browser.IE) {
            window.execScript(code);
        } else if (Prototype.Browser.WebKit) {
            $$("head").first().insert(Object.extend(
                new Element("script", {
                    type: "text/javascript"
                }), {
                    text: code
                }
            ));
        } else {
            window.eval(code);
        }
        // remember included script
        this._loadedScripts.push(script);
    }
};

在javascript中没有import / include / require,但有两种主要方法可以实现你想要的功能:

1 - 您可以使用AJAX调用加载它,然后使用eval。

这是最直接的方法,但由于Javascript的安全设置,它仅限于您的域名,并且使用eval正在为错误和黑客打开大门。

2 - 在HTML中添加脚本标签和脚本URL。

绝对是最好的选择。 您甚至可以从外部服务器加载脚本,并且在使用浏览器分析程序评估代码时它很干净。 您可以将标签放在网页的头部或身体的底部。

这两种解决方案都在这里讨论和说明。

现在,你必须知道一个大问题。 这样做意味着您可以远程加载代码。 现代Web浏览器将加载文件并继续执行当前脚本,因为它们会异步加载所有内容以提高性能。

这意味着,如果直接使用这些技巧,则在您要求将其加载后,您将无法在下一行使用新加载的代码,因为它仍会加载。

EG:my_lovely_script.js包含MySuperObject

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

然后你重新加载页面F5。 它的工作原理! 混乱...

那么该怎么办呢?

那么,你可以使用作者在我给你的链接中建议的黑客行为。 总之,对于匆忙的人来说,当脚本被加载时,他使用en事件来运行回调函数。 所以你可以把所有使用远程库的代码放在回调函数中。 EG:

function loadScript(url, callback)
{
    // adding the script tag to the head as suggested before
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = url;

   // then bind the event to the callback function 
   // there are several events for cross browser compatibility
   script.onreadystatechange = callback;
   script.onload = callback;

   // fire the loading
   head.appendChild(script);
}

然后你编写你想在脚本加载到lambda函数后使用的代码:

var myPrettyCode = function() {
    // here, do what ever you want
};

然后你运行所有这些:

loadScript("my_lovely_script.js", myPrettyCode);

好,我知道了。 但编写所有这些东西是一件痛苦的事情。

那么,在这种情况下,你可以像往常一样使用免费的jQuery框架,它可以让你在一行中完成同样的事情:

$.getScript("my_lovely_script.js", function() {
    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script
});

最近jQuery使用了一个简单得多的版本:

<script src="scripts/jquery.js"></script>
<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  var $head = $("head");
  for (var i = 0; i < js.length; i++) {
    $head.append("<script src="" + js[i] + ""></scr" + "ipt>");
  }
</script>

它在我测试过的每个浏览器都很好用:IE6 / 7,Firefox,Safari,Opera。

更新: jQuery-less版本:

<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  for (var i = 0, l = js.length; i < l; i++) {
    document.getElementsByTagName("head")[0].innerHTML += ("<script src="" + js[i] + ""></scr" + "ipt>");
  }
</script>
链接地址: http://www.djcxy.com/p/1131.html

上一篇: Dynamically load a JavaScript file

下一篇: How to delete a file or folder?