如何获取CSS伪元素的编号值并同步到内容区域?
问题描述
我的项目包含两个板块:Table of Content(目录) 和 content(内容区)。编辑目录列表时,伪元素自动生成的层级编号(如1.1.、1.2...)能正常更新,这部分功能没问题。
目前浏览器显示效果如下:
// table of content
// content
- Vegetables
1.1. Carrot
1.2. Cucumber- Fruits
2.1. Apple
2.2. PineappleVegetables
Carrot
Cucumber
Fruits
Apple
Pineapple
我希望内容区的h1元素也能对应目录的伪元素编号——编辑目录后,内容条目和目录条目拥有完全一致的层级编号。
需要解决的问题:
- 如何在内容区获取伪元素的实际编号值?
- 之前尝试通过
getComputedStyle获取伪元素内容,得到的只是CSS里的表达式文本(如counters(item, ". ")". ";),而非实际渲染的编号(如1.1.),怎么才能拿到真实的编号值?
原始代码
HTML
<ol id="tableOfContent" > <li>Vegetables <ol> <li>Carrot</li> <li>Cucumber</li> </ol> </li> <li>Fruits <ol> <li>Apple</li> <li>Pineapple</li> </ol> </li> </ol> <div id="content"></div>
CSS
ol { counter-reset: item; } ol li { display: block; } ol li::before { content: counters(item, ". ")". "; counter-increment: item; }
JavaScript(无法获取实际编号)
function addTableOfContentEntriesToMainContent(){ const tableOfContent = document.getElementById("tableOfContent"); const content = document.getElementById("content"); const liList = tableOfContent.getElementsByTagName("li"); for (let i = 0; i < liList.length; i++) { const h1 = document.createElement("h1"); h1.textContent = liList[i].firstChild.textContent; content.appendChild(h1); } // 此方法仅返回表达式文本,而非实际编号 const element = liList[0]; const style = window.getComputedStyle(element, '::before'); const pseudoContent = style['content']; console.log(pseudoContent); } addTableOfContentEntriesToMainContent();
解决方案
直接通过getComputedStyle无法获取伪元素渲染后的实际编号,因为浏览器不会将计算后的计数器值暴露给JS。换个思路:通过遍历目录的DOM层级结构,手动计算每个条目的层级编号,再将编号与文本一起添加到内容区。
修改后的JavaScript代码:
function addTableOfContentEntriesToMainContent() { const tableOfContent = document.getElementById("tableOfContent"); const content = document.getElementById("content"); // 递归遍历目录项,计算并生成层级编号 function traverseLi(liElement, parentNumbers = []) { // 获取当前li在父级ol中的位置(从1开始计数) const siblings = Array.from(liElement.parentElement.children); const currentNum = siblings.indexOf(liElement) + 1; // 拼接完整编号(如1.1.) const fullNumber = [...parentNumbers, currentNum].join('.') + '.'; // 创建h1元素,设置编号+文本 const h1 = document.createElement("h1"); h1.textContent = `${fullNumber} ${liElement.firstChild.textContent.trim()}`; content.appendChild(h1); // 递归处理子级ol中的li const childOl = liElement.querySelector('ol'); if (childOl) { Array.from(childOl.children).forEach(childLi => { traverseLi(childLi, [...parentNumbers, currentNum]); }); } } // 处理根目录下的所有li Array.from(tableOfContent.children).forEach(rootLi => { traverseLi(rootLi); }); } addTableOfContentEntriesToMainContent();
说明
- 通过递归遍历目录的DOM结构,记录每个层级的编号,拼接成和伪元素一致的格式
- 不管目录结构如何修改(新增/删除条目、调整层级),编号都会自动匹配目录的伪元素编号
- 无需依赖CSS计数器的计算结果,直接通过DOM层级关系生成对应编号
内容的提问来源于stack exchange,提问作者KeepRunning85
相关产品推荐
相关产品推荐

