You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取CSS伪元素的编号值并同步到内容区域?

问题描述

我的项目包含两个板块:Table of Content(目录) 和 content(内容区)。编辑目录列表时,伪元素自动生成的层级编号(如1.1.、1.2...)能正常更新,这部分功能没问题。

目前浏览器显示效果如下:

// table of content

  1. Vegetables
    1.1. Carrot
    1.2. Cucumber
  2. Fruits
    2.1. Apple
    2.2. Pineapple
// content

Vegetables
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:50:05