[英]How to rebuild DOM?
I need to change a page after load.加载后我需要更改页面。
The source structure here:这里的源结构:
<div id='content'>
<h1>...</h1>
<p>...</p>
<h1>...</h1>
<p>...</p>
<h1>...</h1>
<p>...</p>
</div>
I need to rebuild it to this one:我需要将其重建为这个:
<div id='content'>
<div>
<div>
<h1>...</h1>
<div>
<p>...</p>
</div>
</div>
</div>
<div>
<div>
<h1>...</h1>
<div>
<p>...</p>
</div>
</div>
</div>
<div>
<div>
<h1>...</h1>
<div>
<p>...</p>
</div>
</div>
</div>
</div>
Here is my algorithm:这是我的算法:
const createComplexNode = () => {
const parentBlock = document.querySelector('#content')
const parentContent = parentBlock.querySelectorAll('h1, p')
if (parentContent.length === 0) return
const mainNode = document.createElement('div')
const titleNode = document.createElement('div')
const bodyNode = document.createElement('div')
mainNode.className = 'desc-container'
titleNode.className = 'desc-head'
bodyNode.className = 'desc-body'
const indexes = getIndex(parentContent)
console.log(parentContent[indexes.start])
titleNode.appendChild(parentContent[indexes.start])
for (let i = 1; i <= indexes.end; i++) {
bodyNode.appendChild(parentContent[i])
}
mainNode
.appendChild(titleNode)
.appendChild(bodyNode)
parentBlock.appendChild(mainNode)
return createComplexNode()
}
const getIndex = nodeList => {
const indexes = {
start: -1,
end: -1,
}
const regex = new RegExp('h?')
for (let i = 0; i < nodeList.length; i++) {
if (regex.test(nodeList[i].localName) && indexes.start < 0) {
indexes.start = i
}
if (nodeList[i].localName === 'p') {
indexes.end = i
break
}
}
return indexes
}
My main problem is here const parentContent = parentBlock.querySelectorAll('h1, p')
.我的主要问题是const parentContent = parentBlock.querySelectorAll('h1, p')
。
It's work fine but only on first cycle.它工作正常,但仅在第一个周期。 Because, this function catch all tags in parent node and already wrapped elements too.因为,这个 function 捕获了父节点中的所有标签和已经包装的元素。 It's because of infinity recursion.这是因为无限递归。 How can I prevent it?我该如何预防?
With some utility functions for querying and creating DOM Elements, and the .append()
method:使用一些用于查询和创建 DOM 元素的实用函数以及.append()
方法:
// DOM Utility functions: const EL = (sel, el) => (el || document).querySelector(sel); const ELS = (sel, el) => (el || document).querySelectorAll(sel); const ELNew = (tag, prop) => Object.assign(document.createElement(tag), prop); // Recreate DOM: const EL_content = EL("#content"); const ELS_h1 = ELS("h1", EL_content); ELS_h1.forEach(EL_h1 => { const EL_div_outer = ELNew("div", {className: "wrapper-outer"}); const EL_div_inner = ELNew("div", {className: "wrapper-inner"}); const EL_div_parag = ELNew("div", {className: "wrapper-parag"}); const EL_p = EL_h1.nextElementSibling; EL_div_outer.append(EL_div_inner); EL_div_inner.append(EL_h1, EL_div_parag); EL_div_parag.append(EL_p); EL_content.append(EL_div_outer); });
div { padding: 10px; background: rgba(0,0,0, 0.1); }
<div id="content"> <h1>Title 1</h1> <p>Paragraph 1</p> <h1>Title 2</h1> <p>Paragraph 2</p> <h1>Title 3</h1> <p>Paragraph 3</p> </div>
h1
Elements inside "#content"
and loop them using NodeList.prototype.forEach()定位"#content"
中的所有h1
元素并使用NodeList.prototype.forEach()循环它们h1
's next sibling p
element using Element.nextElementSibling .在循环内,使用Element.nextElementSibling收集h1
的下一个同级p
元素。ELNew
function)使用Document.createElement()创建所需的包装器(使用实用程序ELNew
函数).append()
to move the elements within each other, and reinsert them to the parent "#content"
使用.append()
将元素相互移动,并将它们重新插入到父"#content"
The code is pretty minimal, clean, and should be self-explanatory.代码非常简洁,干净,应该是不言自明的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.