我可以提到一些替代方案来克服这一要求:
使用库注入依赖项(AMD 或 CommonJS 模块)
只需使用模块。ES2015: import
/export
或 CommonJS: require()
.
- 以编程方式创建
script
标签并设置回调onload
,以便在异步加载脚本时做出反应。该属性async = true
是默认设置的。
如果允许您修改要注入的脚本,请在脚本末尾添加一行,使用object
orarray
来跟踪已加载的脚本。
- 您可以将脚本作为文本 ( ) 获取,然后以所需的顺序使用脚本
XMLHttpRequest
构建一个,最后,通过string
eval()
- 而不太推荐但经常使用的选项,设置 a
setInterval
以检查脚本是否已执行。
我建议选择第一个选项。但出于学术目的,我将说明第二种选择:
以编程方式创建script
标签并设置回调onload
,以便在异步加载脚本时做出反应。
我想推荐一本关于脚本加载器的读物:深入了解脚本加载的浑水,半小时值得!
下面的例子是一个管理脚本注入的小模块,这是它背后的基本思想:
let _scriptsToLoad = [
'path/to/script1.js',
'path/to/script2.js',
'path/to/script3.js'
];
function createScriptElement() {
// gets the first script in the list
let script = _scriptsToLoad.shift();
// all scripts were loaded
if (!script) return;
let js = document.createElement('script');
js.type = 'text/javascript';
js.src = script;
js.onload = onScriptLoaded;
let s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(js, s);
}
function onScriptLoaded(event) {
// loads the next script
createScriptElement();
};
在这个plunker 中,您可以按特定顺序异步测试脚本注入:
主要思想是创建一个 API,允许您通过公开以下方法与要注入的脚本进行交互:
addScript
:接收要加载的每个脚本的 URL 或 URL 列表。
load
:运行任务以指定顺序加载脚本。
reset
:清除脚本数组,或取消脚本加载。
afterLoad
: 每个脚本加载后执行的回调。
onComplete
: 加载所有脚本后执行的回调。
我喜欢Fluent 接口或方法链接技术,所以我以这种方式构建了模块:
scriptsLoader
.reset()
.addScript("script1.js")
.addScript(["script2.js", "script3.js"])
.afterLoad((src) => console.warn("> loaded from jsuLoader:", src))
.onComplete(() => console.info("* ALL SCRIPTS LOADED *"))
.load();
在上面的代码中,我们首先加载"script1.js"
文件,并执行afterLoad()
回调,接下来,对所有脚本执行相同的操作,"script2.js"
并且"script3.js"
在加载完所有脚本后,onComplete()
执行回调。