html 中脚本插入的奇怪行为
Weird behavior on script insertion in html
我想在页脚 html 部分插入 2 个脚本,但我有一个奇怪的行为。如果我在 html 本身中使用标签手动插入,它会起作用 (index1.html)。但是,如果我使用 IIFE 创建标签并将它们插入相同的位置和相同的顺序 (index2.html),则控制台中会显示一条错误消息 'dummy variable is not defined'。常识告诉我这个错误很好(因为 dummy 是在使用后定义的),但为什么它适用于 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; // NEW LINE
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()
。
让我们看看文档是怎么说的:
The .ready() method offers a way to run JavaScript code as soon as the page's Document Object Model (DOM) becomes safe to manipulate. [jQuery]
The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. [MDN]
在第一个示例中,DOMContentLoaded
在加载 JS 文件后触发:
在第二个示例中,DOMContentLoaded
立即触发,无需等待 JS 文件:
这就是为什么您需要使用 $(window).on("load", function() {});
而不是 $(document).ready(function() {});
我想在页脚 html 部分插入 2 个脚本,但我有一个奇怪的行为。如果我在 html 本身中使用标签手动插入,它会起作用 (index1.html)。但是,如果我使用 IIFE 创建标签并将它们插入相同的位置和相同的顺序 (index2.html),则控制台中会显示一条错误消息 'dummy variable is not defined'。常识告诉我这个错误很好(因为 dummy 是在使用后定义的),但为什么它适用于 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; // NEW LINE
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()
。
让我们看看文档是怎么说的:
The .ready() method offers a way to run JavaScript code as soon as the page's Document Object Model (DOM) becomes safe to manipulate. [jQuery]
The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. [MDN]
在第一个示例中,DOMContentLoaded
在加载 JS 文件后触发:
在第二个示例中,DOMContentLoaded
立即触发,无需等待 JS 文件:
这就是为什么您需要使用 $(window).on("load", function() {});
而不是 $(document).ready(function() {});