jquery 只动态包含一次JavaScript文件

von4xj4u  于 2023-05-17  发布在  jQuery
关注(0)|答案(4)|浏览(163)

我有一个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文件都被包括在这种方式。

有人能解释一下第二个片段中的行为吗?

e5nszbig

e5nszbig1#

在这种情况下,jQuery有点笨;它完全不像你所期望的那样。当append($node) jQuery这样做时:

jQuery.ajax({
  url: $node.src,
  async: false,
  dataType: "script"
})

哎呀!对于本地文件(例如在同一个域上),jQuery对.js文件体执行标准的XMLHttpRequest,并通过创建<script>标记(再次!)并将它的 contents 设置为.js文件体。这是在全局上下文中模拟eval
对于跨域文件,由于同域策略,jQuery无法执行标准的XMLHttpRequest,因此jQuery再次创建<script>元素并将其插入<head>
在上面的本地和跨域情况下,jQuery finally 都可以做到这一点:

head.removeChild(script);

和 * 繁荣 * 您的.length检查!真扫兴
所以,关于你的问题,不要用这个来打扰jQuery。就这么做

document.getElementsByTagName('head')[0]
  .appendChild(
    document.createElement('script')
  )
  .src = filename;

它将执行您所期望的操作,特别是稍后查询它。

ztmd8pv5

ztmd8pv52#

你试图解决一个已经解决了好几次的问题。例如LazyLoad。jQuery也有类似的插件。

nwnhqdif

nwnhqdif3#

不设置script-tag的source属性,而是设置script tag的“text”属性。这适用于所有 * 现代 * 浏览器(我实际使用的应用程序不支持IE6,所以我不知道这个蠕变...)。
在实践中,它看起来像这样(你必须添加代码来省略你自己的双重包含-例如。一个简单的数组所有已加载的脚本,虽然这是非常具体的应用程序,为什么你要加载代码两次?尝试省略双重加载代码…!):

var script_source_code_string = <some dynamically loaded script source code>;
var $n = $("<script></script>");
$n.get(0).text = script_source_code_string;
$(document.body).append($n);

或者更简单(没有jquery,我这个阶段的代码不知道jquery,也可能是动态加载的):

var script_source_code_string = <some dynamically loaded script source code>;
var s = document.createElement('script');
document.getElementsByTagName('head')[0].appendChild(s);
s.text = script_source_code_string;
rur96b6h

rur96b6h4#

这是我用来将外部脚本和样式文件动态加载到页面中的函数,考虑到不加载脚本两次并检测'.css'和'.js'扩展名。

function lazyLoad(src) {
    head = document.getElementsByTagName('head')[0];
    if (head.innerHTML.search(src) == -1) {
        if (src.search('.js') > -1) {
            var node = document.createElement('script');
            node.src = src;
            node.async = false;
            node.setAttribute('charset', 'utf-8');
        
            head.appendChild(node);
        } else if (src.search('.css') > -1) {
            var node = document.createElement('link');
            node.href = src;
            node.setAttribute('rel', 'stylesheet');
            node.setAttribute('charset', 'utf-8');

            head.appendChild(node);
        }
    }
}

相关问题