我有一个JavaScript函数,我正在写,这是用来包括一个外部JS文件,但只有一次。我需要这样一个函数的原因是,当一些内容通过 AJAX 加载时,它会被调用,我需要对这些内容运行特定于页面的代码(不,仅仅使用.live
是不够的)。
以下是我的尝试,为简洁起见,我将其缩短:
$.include_once = function(filename) {
if ($("script[src='" + filename + "']").length === 0) {
var $node = $("<script></script>")
.attr({
src : filename,
type : "text/javascript"
})
;
$(document.body).append($node);
}
};
这样做效果很好:函数被调用,它加载外部文件,并且该文件在加载时正在运行。太好了
问题是它总是会重新加载该外部文件:我用来检查脚本是否存在的查询总是一无所获!
在调试时,我添加了一些行:
alert($("script").length); // alerts: 4
$(document.body).append($node);
alert($("script").length); // alerts: 4
查看动态源代码(Firebug的HTML选项卡),我根本找不到script标记。
我知道我可以维护一个数组的文件,我以前包括,但我希望去与这样的方法,其中(如果它工作),似乎有点更健壮,因为不是所有的JS文件都被包括在这种方式。
有人能解释一下第二个片段中的行为吗?
4条答案
按热度按时间e5nszbig1#
在这种情况下,jQuery有点笨;它完全不像你所期望的那样。当
append($node)
jQuery这样做时:哎呀!对于本地文件(例如在同一个域上),jQuery对.js文件体执行标准的
XMLHttpRequest
,并通过创建<script>
标记(再次!)并将它的 contents 设置为.js文件体。这是在全局上下文中模拟eval
。对于跨域文件,由于同域策略,jQuery无法执行标准的
XMLHttpRequest
,因此jQuery再次创建<script>
元素并将其插入<head>
。在上面的本地和跨域情况下,jQuery finally 都可以做到这一点:
和 * 繁荣 * 您的
.length
检查!真扫兴所以,关于你的问题,不要用这个来打扰jQuery。就这么做
它将执行您所期望的操作,特别是稍后查询它。
ztmd8pv52#
你试图解决一个已经解决了好几次的问题。例如LazyLoad。jQuery也有类似的插件。
nwnhqdif3#
不设置script-tag的source属性,而是设置script tag的“text”属性。这适用于所有 * 现代 * 浏览器(我实际使用的应用程序不支持IE6,所以我不知道这个蠕变...)。
在实践中,它看起来像这样(你必须添加代码来省略你自己的双重包含-例如。一个简单的数组所有已加载的脚本,虽然这是非常具体的应用程序,为什么你要加载代码两次?尝试省略双重加载代码…!):
或者更简单(没有jquery,我这个阶段的代码不知道jquery,也可能是动态加载的):
rur96b6h4#
这是我用来将外部脚本和样式文件动态加载到页面中的函数,考虑到不加载脚本两次并检测'.css'和'.js'扩展名。