如何用JavaScript拆分HTML结构,将标题与对应内容分入独立div?
问题描述
现有一段结构不确定的HTML,里面所有标题都用<strong>标签标识,原始结构如下:
<body> <p><strong>First title</strong></p> <p>One paragraph</p> <p><strong>Second title</strong></p> <p>One paragraph</p> <p>One paragraph</p> <p><strong>Third</strong></p> <p>One paragraph</p> <ul> <li>something</li> <li>something</li> </ul> <p><strong>Fourth Title</strong></p> <ul> <li>something</li> <li>something</li> </ul> </body>
需要把内容重新整理成:每个带<strong>的标题单独放进一个<div>,这个标题到下一个标题之间的所有内容也单独放进另一个<div>,最终效果如下:
<div> <p><strong>First title</strong></p> </div> <div> <p>One paragraph</p> </div> <div> <p><strong>Second title</strong></p> </div> <div> <p>One paragraph</p> <p>One paragraph</p> </div> <div> <p><strong>Third</strong></p> </div> <div> <p>One paragraph</p> <ul> <li>something</li> <li>something</li> </ul> </div> <div> <p><strong>Fourth Title</strong></p> </div> <div> <ul> <li>something</li> <li>something</li> </ul> </div>
之前尝试用querySelectorAll("body > *")逐个遍历元素,结果标题和对应的内容块错位,没法正确分组。
解决方案
核心思路就是以带<strong>的标题元素为分界点,把标题和它对应的内容块分别打包,具体步骤如下:
- 先找到所有body下、包含
<strong>的标题元素(这里都是<p>标签); - 挨个处理每个标题:给标题套个div,再把这个标题到下一个标题之间的所有内容也套个div;
- 最后把这些新生成的div替换掉原来的body内容。
完整代码实现
// 选中所有body下带strong的p标签(也就是标题块) const titleElements = document.querySelectorAll('body > p:has(strong)'); // 创建一个临时容器放新结构,避免直接操作body导致混乱 const container = document.createElement('div'); titleElements.forEach((titleEl, index) => { // 给标题单独套div const titleDiv = document.createElement('div'); titleDiv.appendChild(titleEl.cloneNode(true)); container.appendChild(titleDiv); // 收集当前标题到下一个标题之间的所有内容 const contentDiv = document.createElement('div'); let nextEl = titleEl.nextElementSibling; // 一直收集,直到碰到下一个标题或者没有元素为止 while (nextEl && !nextEl.querySelector('strong')) { contentDiv.appendChild(nextEl.cloneNode(true)); nextEl = nextEl.nextElementSibling; } // 只有内容div里有东西才添加 if (contentDiv.children.length > 0) { container.appendChild(contentDiv); } // 加个换行分隔,和示例效果对齐(可选) container.appendChild(document.createTextNode('\n\n')); }); // 清空原body内容,把新结构放进去 document.body.innerHTML = ''; document.body.appendChild(container);
代码说明
- 用
:has(strong)选择器精准定位标题元素,不会误选其他不带strong的p标签; - 通过
nextElementSibling逐个遍历标题后面的元素,直到遇到下一个标题就停止,这样就能准确把每个标题对应的内容块捞出来; - 用
cloneNode(true)复制元素和它的所有子节点,避免直接移动原始元素导致DOM结构乱掉; - 临时容器
container用来组装新结构,最后一次性替换body内容,比边改边渲染更高效。
内容的提问来源于stack exchange,提问作者Smeagol2
相关产品推荐
相关产品推荐

