gpt4 book ai didi

javascript - 动态包含 JavaScript 并等待

转载 作者:搜寻专家 更新时间:2023-11-01 04:11:37 25 4
gpt4 key购买 nike

我想做的是在 Javascript 中动态包含一个或多个 js 文件。我知道有很多技术可以解决这个问题,但我正在寻找遵循这些规则的解决方案:

1) 不使用任何 JS 框架或库(jQuery、Prototype 等)。

2) 脚本应该停止执行,直到外部 js 文件被浏览器完全加载和解析。

#2 背后的理由是外部 js 文件将包含需要在包含脚本后立即使用的函数定义。大多数情况下,在我开始调用这些函数之前,浏览器没有时间解析 js 文件。

我不介意使用回调来了解脚本何时完成加载,但是:

1) 我事先不知道要动态包含多少脚本,所以我不想也不能写一堆嵌套的回调。我只需要知道它们何时全部加载完毕。

2) 我的意思是,如果浏览器缓存了 JavaScript,则尝试使用某种“加载”事件来触发回调可能无法正常工作。

编辑 我应该从一开始就提到这是一个插件系统,但我想让我的问题/答案足够通用,以便对其他人有所帮助。

用户可以在一个数组中定义他们想要加载的插件。

plugins = [ 'FooPlugin', 'BarPlugin' ];

然后我将遍历数组,并为每个插件加载 js 脚本:

for(var i = 0; i < plugins.length; i++) {
loadScript('plugins/' + plugins[i] + '.js');
}

每个插件将自己推送到 loaded_plugins 数组(这是 FooPlugin.js 的示例)

load_plugins.push({
name: 'FooPlugin',
// Other plugin methods and properties here
});

最佳答案

跨浏览器工作,从 IE6 开始。

document.loadScript = function (src, callback) {
function script(src, onload) {
var scriptTag = document.createElement('script');
if (onload) scriptTag.onload = onload;
scriptTag.src = src;
scriptTag.type = 'text/javascript';
return scriptTag;
}
function outer(tag) {
var d = document.createElement('div');
d.appendChild(tag);
return d.innerHTML;
}
if (!(src instanceof Array)) src = [src];
var i, scr,
callbackId = 'dynCall_'+Math.floor(Math.random()*89999+10000);
counter = src.length,
call = function () { if (--counter == 0) callback(); };
if (!document.body) {
window[callbackId] = function () {
delete window[callbackId];
if (callback instanceof Function) callback();
};
for (i=0; i<src.length; i++) document.write(outer(script(src[i])));
document.write('<scr'+'ipt type="text/javascript">'+'window.'+callbackId+'();'+'</scr'+'ipt>');
return;
}
for (i=0; i<src.length; i++) document.body.appendChild(script(src[i], call));
};

缩小/混淆:

(function(){document.loadScript=function(src,callback){function script(src,onload){var scriptTag=document.createElement('script');if(onload)scriptTag.onload=onload;scriptTag.src=src;scriptTag.type='text/javascript';return scriptTag}function outer(tag){var d=document.createElement('div');d.appendChild(tag);return d.innerHTML}if(!(src instanceof Array))src=[src];var i,scr,callbackId='dynCall_'+Math.floor(Math.random()*89999+10000);counter=src.length,call=function(){if(--counter==0)callback()};if(!document.body){window[callbackId]=function(){delete window[callbackId];if(callback instanceof Function)callback()};for(i=0;i<src.length;i++)document.write(outer(script(src[i])));document.write('<scr'+'ipt type="text/javascript">'+'window.'+callbackId+'();'+'</scr'+'ipt>');return}for(i=0;i<src.length;i++)document.body.appendChild(script(src[i],call))};document.loadScript.toString=function(){return'function loadScript() { [obfuscated] }'}})();

分支的快速解释:

如果调用 loadScript 的脚本标签位于文档头部或正文中,则 document.body 将是未定义的,因为 DOM 尚未在其中。因此,我们不能使用附加标签的标准方法,我们必须使用 doc write。这样做的好处是我们写的标签会按一定的顺序发生,但缺点是我们必须有一个全局范围的回调函数。

与此同时,如果我们有 document.body,我们就可以正确地执行它(-ish - 当周围没有库可以帮助正确地执行它时,我们会做出牺牲 - 呃,因此 .onload()。不过,它是不像我们要在脚本标签上抛出很多事件,所以它可能没问题。)缺点(也许?)是脚本都是异步加载的,所以我们需要在它们加载时运行倒计时.

关于javascript - 动态包含 JavaScript 并等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3955770/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com