我想在页脚html部分插入2个脚本,但是我的行为很奇怪。如果我在html本身中使用标签手动插入,则它可以正常工作(index1.html)。但是,如果我使用IIFE创建标签并以相同的位置和相同的顺序(index2.html)插入标签,则会在控制台中显示一条错误消息,提示“未定义虚拟变量”。常识告诉我该错误很好(因为使用哑元后会定义它),但是为什么它可用于index1.html?
index1.html:
...
<script src="script1.js" async></script>
<script src="script2.js"></script>
</body>
</html>
index2.html:
...
<script>
(function(){
var loadScript = function(data, callback) {
var script = document.createElement('script');
script.src = data.src;
if (data.opts) {
if (data.opts.async) script.async = data.opts.async;
}
document.body.appendChild(script);
}
var loadScriptRecursive = function(scripts, index) {
loadScript(scripts[index], function () {
if (++index < scripts.length) loadScriptRecursive(scripts, index);
});
}
var scripts = [{src: 'script1.js'}, {src: 'script2.js', opts: {async: false}}];
loadScriptRecursive(scripts, 0);
})()
</script>
</body>
</html>
script1.js:
$(document).ready(function () {
if (dummy) ...
...
}
script2.js:
var dummy = true
首先,您声明callback
,但从未使用过它。我假设您的意思是这样的script.onload = callback;
。
(function() {
var loadScript = function(data, callback) {
var script = document.createElement("script");
script.src = data.src;
script.onload = callback;
if (data.opts) {
if (data.opts.async) script.async = data.opts.async;
}
document.body.appendChild(script);
};
var loadScriptRecursive = function(scripts, index) {
loadScript(scripts[index], function() {
if (++index < scripts.length) {
loadScriptRecursive(scripts, index);
}
});
};
var scripts = [
{ src: "script1.js" },
{ src: "script2.js", opts: { async: false } }
];
loadScriptRecursive(scripts, 0);
})();
但是由于$(document).ready()
,不足以解决此问题。
让我们看看文档怎么说:
。ready()方法提供了一种在页面的文档对象模型(DOM)变得可以安全操作后立即运行JavaScript代码的方法。 [jQuery]
DOMContentLoaded事件在初始HTML文档已完全加载并解析,而无需等待样式表,图像和子帧完成加载时触发。 [MDN]
在第一个示例中,DOMContentLoaded
在加载JS文件后触发:
在第二个示例中,DOMContentLoaded
立即触发,而无需等待JS文件:
这就是为什么您需要使用$(window).on("load", function() {});
而不是$(document).ready(function() {});