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

如何用JS为无限嵌套独立文档的h1/h2标题添加可复制编号

实现方案

核心思路是使用**深度优先遍历(DFS)**处理DOM结构,每个独立区块维护专属计数器,遇到嵌套子区块时递归处理,处理完成后回到父级继续遍历,完全匹配从上到下的DOM顺序要求。和全局遍历所有标题的方案不同,该方案只遍历当前区块的直接子元素,天然隔离了不同区块的计数边界,不会出现跨区块计数错误的问题。

实现代码

// 移除标题中原有的序号前缀,避免重复添加
function clearOldNumber(text) {
  return text.replace(/^[\d.\s]+/, '');
}

// 处理单个独立区块的标题序号
function processBlock(blockElement) {
  // 初始化当前区块的独立计数器
  let countH1 = 0;
  let countH2 = 0;
  let countH3 = 0;

  // 遍历当前区块的所有直接子元素
  for (const el of Array.from(blockElement.children)) {
    switch(el.tagName) {
      case 'H1':
        countH1++;
        // 高等级标题更新时,重置所有低等级计数器
        countH2 = 0;
        countH3 = 0;
        el.textContent = `${countH1} ${clearOldNumber(el.textContent)}`;
        break;
      case 'H2':
        countH2++;
        countH3 = 0;
        el.textContent = `${countH1}.${countH2} ${clearOldNumber(el.textContent)}`;
        break;
      case 'H3':
        countH3++;
        el.textContent = `${countH1}.${countH2}.${countH3} ${clearOldNumber(el.textContent)}`;
        break;
      default:
        // 遇到嵌套的独立区块,递归处理
        if (el.classList.contains('text_output_expansion')) {
          processBlock(el);
        }
    }
  }
}

// 调用入口:先处理最外层根区块
processBlock(document.getElementById('text_output'));

功能说明

  • 计数器完全独立:每个.text_output_expansion区块内部的标题计数不会受外层或其他嵌套区块影响
  • 序号可复制:序号直接写入文本节点,复制粘贴文档时会完整保留
  • 可扩展:如果需要支持h4~h6等级的标题,只需按现有规则新增对应计数器和判断分支即可
  • 适配动态更新:如果区块内容有修改,重新调用processBlock方法即可刷新序号,不会出现重复叠加序号的问题

内容的提问来源于stack exchange,提问作者user3787031

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:24:07