我在尝试创建一个脚本,把每一章写作都包裹在一个div元素中,这样就可以在帖子中实现自动排版,而不必每次都手动实现。举一个简单的例子,比如:
<h2>Chapter 1</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <h2>Chapter 2</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <h2>Chapter 3</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <h2>Chapter 4</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p>
然后把它变成:
<div class="chapter" id="chapter-1"> <h2 id="section-1">Chapter 1</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> </div> <div class="chapter" id="chapter-2"> <h2 id="section-2">Chapter 2</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> </div> <div class="chapter" id="chapter-3"> <h2 id="section-3">Chapter 3</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> <p>bla bla bla bla</p> </div> <div class="chapter" id="chapter-4"> <h2 id="section-4">Chapter 4</h2> <p>bla bla bla bla</p> <p>bla bla bla bla</p> </div>
(这样就能完成排版了,但当我把这部分实现好后,感觉会简单得多。)
我认为类似于 -
h2.insertAdjacentHTML("beforebegin", "</div> + <div class='chapter'>")
...会起作用(我得先创建一个起始的
<div></div> <h2>Chapter X</h2> <p>bla bla bla bla</p>
…这并不是我想要的效果。
我确实在这里发现有人遇到类似的问题 这里,但我的JavaScript知识水平已经低到极点,在没有完整示例供参考的情况下,很难复现给出的答案。
这是我当前正在处理的内容:
// 1. Count total amount of chapters in document var chapterCount = document.querySelectorAll("h2").length; // 2. Give all <h2> tags a unique ID, since I can't seem to use insertAdjacentHTML en masse for (let i = 0; i < chapterCount; i++) { document.querySelectorAll("h2")[i].setAttribute("id", "section-" + (i + 1)); } // 3. This one doesn't work, but you can see the logic I'm going for. Select each <h2> individually, then run the insertAdjacentHTML command on loop until there's no more chapters. for (let i = 0; i < chapterCount; i++) { document.querySelectorAll("#section-") + [i].insertAdjacentHTML("beforebegin", "</div> + <div class='chapter'>"); } // 4. Assign each chapter a unique ID, so I can set up tabs without issue for (let i = 0; i < chapterCount; i++) { document.querySelectorAll(".chapter")[i].setAttribute("id", "chapter-" + (i + 1)); }
在第3 步,试图按照另外一个问题的思路来做(这个问题也在此链接旁边被提及 这条链接),我尝试了下面类似的解决方案(这并不能解决把它应用到每个
const targetElement = document.querySelector("h2") const pseudoContainer = document.createElement('div'); pseudoContainer.innerHTML = "</div><div class='chapter'>"; targetElement.insertAdjacentHTML('beforebegin', pseudoContainer.firstChild);
但最终结果始终只返回 [object HTMLDivElement],而不是我输入的内容。(之所以不是奇怪的、不完整的标签导致的,是因为改成随机文本会返回 [object Text]。)把pseudoContainer.innerHTML插入也不起作用,因为它会像我之前遇到的那样,在标题上方返回一个 。
还有哪些建议可以让我继续?我肯定漏掉了一些非常明显的东西,但我尽量避免使用JavaScript,因为缺乏理解他人讨论中术语的经验。不过这个脚本未来会为我省下大量时间,因此我正在一步一步地学习。
提前感谢!!
Selection API的 Range接口提供了一个 surroundContents(newParent) 方法,可以用于此类场景:
surroundContents(newParent)
const headers = document.querySelectorAll("h2"); for (let i = 0; i<headers.length; i++) { const range = new Range(); range.setStartBefore(headers[i]); if (headers[i+1]) { range.setEndBefore(headers[i+1]); } else { // use a better selector if needed const lastP = document.querySelector("body > p:last-of-type"); range.setEndAfter(lastP); } const wrapper = document.createElement("div"); wrapper.classList.add("wrapper"); range.surroundContents(wrapper); }
.wrapper { border: 1px solid; margin: 3px; padding: 6px}