我已经有代码可以根据请求延迟加载脚本。我现在的问题是等待执行某些代码,直到对象可用。我不能使用 setTimeout() 因为它不会阻止执行。
那么在不锁定浏览器的情况下“等待”加载的好方法是什么?
同样,不能使用原始 setTimeout()。
我已经有代码可以根据请求延迟加载脚本。我现在的问题是等待执行某些代码,直到对象可用。我不能使用 setTimeout() 因为它不会阻止执行。
那么在不锁定浏览器的情况下“等待”加载的好方法是什么?
同样,不能使用原始 setTimeout()。
假设您控制脚本的内容,您可以在延迟加载脚本的底部放置一些要执行的代码,以向主页指示脚本已加载。例如,在您的页面中,您可以执行以下操作:
var loadingScripts = 0;
var loadScript = function() {
// Do what you need to do to load the script...
loadingScripts++;
}
var loadedScript = function() {
loadingScripts--;
if (loadingScripts == 0) {
// Kick off execution of code that requires the lazy loaded scripts.
}
}
然后在您的脚本中,将此代码添加到底部:
loadedScript();
您可以使用数组而不是整数来为这个示例增添趣味(以跟踪已加载的特定脚本)。您也可以使用对象来将特定函数调用与特定脚本的完成相关联。我的例子很简单,但问你是否想让我展示如何扩展代码。
这是在加载脚本时如何使用回调继续执行特定代码的方法(同样,假设您控制脚本本身)。
var scriptCallbacks = {}
var loadScript = function(scriptname, callback) {
// Do what you need to load scriptname
scriptCallbacks[scriptname] = callback;
}
var loadedScript = function(scriptname) {
(scriptCallbacks[scriptname])();
}
然后,当您想加载脚本时,您可以执行以下操作...
var callback = function() {
// Write exactly what you want executed once your script is loaded
}
loadScript("MyScript.js", callback);
同样,在你的延迟加载脚本中,只需将此代码添加到底部以通知你的回调触发:
loadedScript("MyScript.js");
实际上,我的做法与丹尼尔提到的不同。所有元素在加载后都会触发 load 事件,并在评估内容后加载 Javascript 文件。因此,您可以设置一个事件处理程序以在它们可用后继续执行:
var loadScript = function(fileName, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = fileName;
script.onload = callback;
script.onreadystatechange = function() {
if(this.readyState == 'complete') {
callback();
}
};
head.appendChild(script);
};
以及一个示例用法:
var bar = function() {
Foo.baz();
};
if(!window.Foo) {
loadScript('Foo.js',bar);
} else {
bar();
}
根据 seanmonstar 的回答,我发现这个 async/await 解决方案运行良好。如果之前已经加载了脚本,它会立即解析,或者在下载脚本后稍后异步解析。
static async loadScript(url){
return new Promise( resolve => {
const element = document.getElementById(url);
if(element){
resolve();
}else{
const script = document.createElement("script");
script.id = url;
script.onload = () => {
resolve();
};
script.src = url;
document.body.appendChild(script);
}
});
}
它是这样使用的:
await loadScript("../libs/geopackage/geopackage.js");