第 1 部分 - 这不是代码的加载方式,只是代码无效,即使在页面上硬编码也无法工作。
“奇怪的是,在插入的 HTML 已经可见后,浏览器会稍作瘫痪。请参阅下面的时间线,我可以在我的屏幕上看到 HTML(带有正确的样式)在大约 5 秒长的 Parse HTML 事件发生之前。”
关于 HTML 的实用性(它的荒谬不言自明)、它的有效性(它不是)和功能性(它不是而且可能从未有过),有一些事情需要解决。
你应该validate your HTML,因为它非常无效,但在我们开始讨论之前,当你决定验证这个烂摊子时,你需要将它分成大约 16 个部分,因为大多数在线服务都会失败或取消验证如果一次处理这么多,请尽早处理。
以下是由于拼写错误而并非孤立问题的问题列表。这些问题重复多次。我最担心的是值和大部分变量似乎是手动定制的。希望我弄错了,您没有花费数小时来定制会阻碍而不是真正有用的值。
14 #accordion- 固定,14 #headingOne - 固定,7 #model,7 #type,7#brand,...
还有更多被骗的#IDs,我将#accordion 更改为#acordion1 为14,因为每个#accordion 都必须起作用,而不仅仅是第一个。与#accordion 有直接关系的所有相关属性也需要更改,为了功能,我再次设法更改toggle-parent="#accodion。因此,有 15 个可运行的手风琴,我添加了一个带有正确设计的手风琴的主页选项卡,如果您决定重新设计其他 14 个手风琴,您可以将其用作模板。
2。要使用 Bootstrap 组件,请按照文档制作。
OP 代码甚至没有任何选项卡,如果您提到
Bootstrap documents 甚至
W3School's short tutorials,您就会知道每个选项卡都需要一个
<a>,所以您的代码很短16
<a> 切换 16 个选项卡。这就是为什么您的页面只显示 16 个选项卡中的第一个选项卡的原因,并不是因为浏览器中途失败了。
3。我注意到的另一件无效的事情是属性readonly(以及在较小程度上的required)应用于几乎所有表单控件。
为什么需要<select> 标记上的readonly 属性? 为元素分配属性时,不要开始为所有内容添加大量属性。混乱使得可读性、维护和调试变得不可能。
4。有 2 个 Plunk:
Plunk 1 是OP(O原始Post)问题的解决方案,详细解释在部分2 这个答案。 HTML 已部分修复,我没有足够的时间修复所有内容。
它有 16 个选项卡和 15 个可工作的手风琴。
加载时间已从 34 秒减少到 2 秒。与边缘。似乎 Edge 英勇地试图理解被解析然后失败的 HTML。 Firefox 和 Chrome 等真正的浏览器只是将其转储并留在那里。
Plunk 2 是来自 OP 代码的 HTML,我的解决方案正在加载它。
结果相同,OP代码失败是因为代码本身,而不是因为加载问题。
第 2 部分 - 一种将大字符串解析为 HTML 的稳定方法。如果 OP 代码确实有效,则不需要。
OP 在尝试通过
innerHTML 向 DOM 添加大量标记时遇到严重延迟。使用 Edge 完全渲染它最多需要 34 秒,而其他浏览器 OP 报告为 3 秒。
我在 Edge 上将加载时间缩短到 2 到 3 秒,并在真实浏览器(Chrome 和 Firefox)上立即加载。
虽然 OP 已经尝试使用 createDocumentFragment(),但我相信它是快速加载和解析所述 HTML 的关键。 OP 可能没有使用的其他关键组件是:
insertAdjacentHTML() 和 Immediately Invoked Function Expression
使用 insertAdjacentHTML() 方法而不是 innerHTML 属性。 insertAdjacentHTML() 是innerHTML 的强大且多功能的版本。
相似之处:
两者都将采用给定的字符串并解析为 HTML。
两者都很快。
区别:
insertAdjacentHTML() 将 HTML 插入 DOM,它不会覆盖元素中或 DOM 中任何地方的任何现有 HTML。 innerHTML 覆盖元素的内部。
innerHTML 指向一个元素,它将接受一个字符串并用给定的字符串覆盖所述元素的所有内容。如果innerHTML 只是指向一个没有字符串的元素,那么它将返回该元素的 HTML 内容。 innerHTML GET 的能力是 insertAdjacentHTML() 它不能做的唯一事情。相比之下,insertAdjacentHTML() 的 SET 功能非常强大,如下所述:insertAdjacentHTML() 不仅通过引用元素被引导,它还通过其第一个参数准确地告知与引用元素相关的位置这是与 position 相关的 4 个 DOMString 之一:
"beforebegin" 将字符串放置在元素的beginning 之前。
`$elector.before(str)`★
"afterend" 将字符串放置在元素的end 之后。
`$elector.after(str)`★
"afterbegin" 将字符串放在元素的右侧 brgin之后>宁。换句话说,字符串被插入到元素的内容之前。
`$elector.prepend(str)`★
"beforeend" 将字符串在元素的右边before end >。基本上,字符串放在元素内容之后。这个位置对于速度是最优化的,因为没有后续的兄弟姐妹可以减慢速度。
`$elector.append(str)`★
insertAdjacentHTML() 第二个参数是要解析成 HTML 的字符串。使用Template Literals 代替文字字符串可以让我们更轻松地进行字符串操作。
`element.insertAdjacentHTML("beforeend", <input id="${ID+i}" type="${typeArr[i]}" value="${Math.floor(Math.random() * i}">)`
立即调用函数表达式是一个具有特殊模式的函数。
这些条件使 IIFE 成为一次性的事情。 IIFE 的签名略有不同,但其要点如下:
`(function() { var x = function() {...} x})();`
DOM 操作是处理器密集型的,我们越避免它越好。 DocumentFragment 是为了让我们完成所有涉及 DOM 的琐碎但大量的任务——脱离 DOM。我们可以向 DocumentFragment 及其后代添加尽可能多的元素、文本、属性、设置事件处理程序等,而无需接触 DOM。一切完成后,只需要进行一次 DOM 操作:
`document.body.appendChild(frag);`
演示 - 如果您想测试实际工作的演示,请查看此Plunk
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Monstrosity</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
(function() {
const str = `Huge Disaster of HTML`
const frag = document.createDocumentFragment();
const node = document.createElement('div');
let build = function(node, str, frag) {
node.insertAdjacentHTML('beforeend', str);
frag.appendChild(node);
document.body.appendChild(frag);
}
build(node, str, frag);
}());
</script>
</body>
</html>