首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >动态加载JavaScript文件

动态加载JavaScript文件
EN

Stack Overflow用户
提问于 2008-08-21 21:59:31
回答 29查看 190.7K关注 0票数 185

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

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

主流JavaScript库是如何实现这一点的(Prototype、jQuery等)?这些工具是否将多个JavaScript文件合并到脚本文件的一个可重新发布的“构建”版本中?或者他们会动态加载辅助的“库”脚本吗?

对这个问题的补充是:在加载动态包含的JavaScript文件后,是否有方法处理该事件? Prototype具有针对文档范围事件的document.observe。示例:

代码语言:javascript
复制
document.observe("dom:loaded", function() {
  // initially hide all containers for tab content
  $$('div.tabcontent').invoke('hide');
});

脚本元素有哪些可用事件?

EN

回答 29

Stack Overflow用户

回答已采纳

发布于 2008-10-28 09:02:37

您可以使用Prototypes动态创建脚本元素

代码语言:javascript
复制
new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

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

我们通常希望我们的依赖代码在下一行,并且喜欢写下这样的代码:

代码语言:javascript
复制
if (iNeedSomeMore) {
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
    myFancyMethod(); // cool, no need for callbacks!
}

有一种智能的方法可以注入脚本依赖项,而不需要回调。您只需通过同步AJAX请求拉取脚本并在全局级别评估脚本即可。

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

代码语言:javascript
复制
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);
    }
};
票数 88
EN

Stack Overflow用户

发布于 2013-02-09 17:37:51

javascript中没有import / include / require,但有两种主要方法可以实现您想要的结果:

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

这是最直接的方法,但由于Javascript的安全设置,它仅限于您的域,使用eval会打开漏洞和黑客的大门。

2-在HTML中添加带有脚本URL的脚本元素。

这绝对是最好的办法。您甚至可以从外部服务器加载脚本,并且当您使用浏览器解析器评估代码时,脚本是干净的。您可以将script元素放在网页的head元素中,或放在body的底部。

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

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

这意味着如果你直接使用这些技巧,你将不能在你请求加载后的下一行使用新加载的代码,因为它仍然在加载。

例如: my_lovely_script.js包含MySuperObject

代码语言:javascript
复制
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 event在脚本加载时运行回调函数。因此,您可以将使用远程库的所有代码放入回调函数中。例如:

代码语言:javascript
复制
function loadScript(url, callback)
{
    // adding the script element 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函数中加载脚本后,编写要使用的代码:

代码语言:javascript
复制
var myPrettyCode = function() {
    // here, do what ever you want
};

然后运行所有这些操作:

代码语言:javascript
复制
loadScript("my_lovely_script.js", myPrettyCode);

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

好吧,在这种情况下,你可以一如既往地使用神奇的免费jQuery框架,它让你在一行中做同样的事情:

代码语言:javascript
复制
$.getScript("my_lovely_script.js", function() {
    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script
});
票数 84
EN

Stack Overflow用户

发布于 2008-08-23 15:52:49

我在jQuery中使用了much less complicated version recently

代码语言:javascript
复制
<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版本:

代码语言:javascript
复制
<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>
票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档