<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>demo</title>
</head>
<body>
<script>
const handError = (srcEle, num = 1) => {
console.log(srcEle.src, ' is error');
const url = new URL(srcEle.src);
const newUrl = 'test' + srcEle.src.split('/').pop();
const newSrciptStr = `<script src=${newUrl} onerror="handError(this)" onload="handLoad(this)"><\/script>`;
document.write(newSrciptStr);
// const scriptObj = document.createElement('script');
// scriptObj.src = newUrl;
// scriptObj.setAttribute('onerror', 'handError(this)');
// scriptObj.setAttribute('onload', 'handLoad(this)');
// document.body.appendChild(scriptObj);
};
const handLoad = (srcEle) => {
console.log(srcEle.src, ' is loaded');
};
window.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoad');
});
</script>
<div>demo</div>
<script defer src="./1.js" onerror="handError(this)" onload="handLoad(this)"></script>
<script defer src="./2.js" onerror="handError(this)" onload="handLoad(this)"></script>
<script defer src="./3.js" onerror="handError(this)" onload="handLoad(this)"></script>
</body>
</html>
为什么使用doeument.write不能重载异步脚本2.js和3.js,而使用appendChild能全部重载。图3为注释write使用appendChild的结果,图4为删除defer属性后使用write能够正常重载。
目前估计产生问题的原因在:defer属性的异步加载脚本与DOMContentLoaded以及document.write的这三者之间有某种连系,导致在第一次写入脚本后,覆盖了页面,并一直处于DOMContentLoaded前的状态。具体是什么原因导致的,希望大神们能解惑。
在解释为什么使用 document.write
不能重载多个带有 defer
属性的脚本,而使用 appendChild
可以成功重载所有脚本之前,我们需要理解几个关键概念和它们之间的相互作用。
defer
属性的作用当 <script>
标签具有 defer
属性时,它告诉浏览器该脚本将延迟执行,直到文档完全解析和显示之后(即 DOMContentLoaded 事件触发之后),并且脚本将按照它们在文档中出现的顺序执行。
document.write
的行为document.write
方法主要用于在文档加载和解析过程中向文档输出内容。然而,一旦文档加载完成(即 DOMContentLoaded
事件触发后),再调用 document.write
会导致页面被重写,这通常不是你想要的结果。在这种情况下,它会导致整个页面内容被新的 <script>
标签替换,从而中断当前脚本的执行和其他任何 defer
脚本的加载和执行。
在你的例子中,当第一个 defer
脚本(如 ./1.js
)发生错误时,handError
函数被调用,它试图通过 document.write
动态添加一个新的 <script>
标签来“重载”脚本。然而,由于此时文档可能已经完成了加载(至少是 DOMContentLoaded 事件已经触发),document.write
的调用会重写整个页面,包括已经加载的 DOM 和后续将要加载的 defer
脚本(如 ./2.js
和 ./3.js
)。因此,这些脚本不再加载或执行。
appendChild
可以工作使用 appendChild
方法动态添加 <script>
标签不会重写整个页面,而是将新的 <script>
元素添加到 DOM 中。这允许页面保持其现有内容不变,并且新的脚本标签可以像页面中的其他脚本一样正常加载和执行,即使它们是在 DOMContentLoaded 事件之后添加的。
因此,当你需要在文档加载完成后动态添加脚本时,应该使用 appendChild
或其他 DOM 操作方法,而不是 document.write
。这样可以避免重写整个页面并保留页面的当前状态,包括已经加载和将要加载的其他脚本。
问题内容: 我知道这被认为是不良做法;并且,我希望整理出一份为什么要向第三方供应商提交的原因清单,说明为什么他们不应该在其分析代码的实现中使用它们。 请在下面说明您提出不良做法的理由。 问题答案: 一些较严重的问题: document.write(此后称为DW)在XHTML中不起作用 DW不会直接修改DOM,从而阻止了进一步的操作 (试图寻找证据,但充其量只是视情况而定) 页面加载完成后执行的DW
问题内容: 在教程中,我学会了使用。现在,我了解到,很多人对此表示反对。我已经尝试过,但随后它实际上将其发送到打印机。 那么我应该使用哪些替代方法,为什么不使用呢?w3schools和MDN都使用。 问题答案: 作为推荐的替代方法,您可以使用DOM操作直接查询节点元素并将其添加到DOM。
chrome浏览器 onclick链接 O:https://www.w3schools.com窗口打开 X:about:空白窗口打开
我无法理解为什么以下操作不起作用? 我一直收到错误: 我尝试使用通用参数: 我好像想不出来。 我完全错过了什么? 我正在使用OpenJDK 11。
考虑以下示例:
如果我的理解是正确的,那么为什么不将的==和!=运算符重载为: 那我们就可以省下两个铸件了?