javascript - 对 h1、h2 标题、重置计数器的嵌套文档进行编号

标签 javascript html jquery css recursion

我希望向标题添加数字,如下所示。问题在于,有些文档可能无限嵌套,需要独立计数。在原始文档中,标题仅为文本,没有编号前缀。

<div id="text_output">
  <h1>Document 1</h1>
    <h2>1 Heading</h2>
      <h3>1.1 Subheading</h3>
      <h3>1.2 Subheading</h3>
        <div class="text_output_expansion">
          <h1>Document 2</h1>
            <h2>1 Heading</h2>
              <h3>1.1 Subheading</h3>
            <h2>2 Heading</h2>
              <h3>2.1 Subheading</h3>
        </div>
      <h3>1.3 Subheading</h3>
    <h2>2 Heading</h2>
      <h3>2.1 Subheading</h3>
      <h3>2.2 Subheading</h3>
        <div class="text_output_expansion">
          <h1>Document 3</h1>
            <h2>1 Heading</h2>
              <h3>1.1 Subheading</h3>
            <h2>2 Heading</h2>
              <h3>2.1 Subheading</h3>
                <div class="text_output_expansion">
                  <h1>Document 4</h1>
                    <h2>1 Heading</h2>
                      <h3>1.1 Subheading</h3>
                    <h2>2 Heading</h2>
                      <h3>2.1 Subheading</h3>
                </div>
              <h3>2.2 Subheading</h3>
        </div>
      <h3>2.3 Subheading</h3>
    <h2>3 Heading</h2>
      <h3>3.1 Subheading</h3>
      <h3>3.2 Subheading</h3>
</div>

我将发布一个 CSS 解决方案,但我只是在努力让它在 javascript 中工作。这个想法是为了让我可以复制并粘贴带有完整数字的文档(CSS 解决方案不允许这样做)。诚然,我的 javascript 不太好,但我的困难似乎是 js 如何从上到下循环遍历元素。

最佳答案

您可以通过对 h 标记 block 进行分组来递归遍历结构:

var div = document.createElement("div");
div.innerHTML = `<div id="text_output">
  <h1>Document</h1>
    <h2>Heading</h2>
      <h3>Subheading</h3>
      <h3>Subheading</h3>
        <div class="text_output_expansion">
          <h1>Document</h1>
            <h2>Heading</h2>
              <h3>Subheading</h3>
            <h2>Heading</h2>
              <h3>Subheading</h3>
        </div>
      <h3>Subheading</h3>
    <h2>Heading</h2>
      <h3>Subheading</h3>
      <h3>Subheading</h3>
        <div class="text_output_expansion">
          <h1>Document</h1>
            <h2>Heading</h2>
              <h3>Subheading</h3>
            <h2>Heading</h2>
              <h3>Subheading</h3>
                <div class="text_output_expansion">
                  <h1>Document</h1>
                    <h2>Heading</h2>
                      <h3>Subheading</h3>
                    <h2>Heading</h2>
                      <h3>Subheading</h3>
                </div>
              <h3>Subheading</h3>
        </div>
      <h3>Subheading</h3>
    <h2>Heading</h2>
      <h3>Subheading</h3>
      <h3>Subheading</h3>
</div>`
document.querySelector('body').appendChild(div)

function number_headings(root){
    var h1 = 1;
    function label_headings(nodes, p){
       var [groups, group, h] = [[], [], null]
       for (var i of nodes){
          if (i.tagName[0].toLowerCase() != 'h' || (h != null && i.tagName != h.tagName)){
             group.push(i)
          }
          else if (h === null){
             h = i;
          }
          else{
             groups.push({node:h, block:group.slice()});
             group = [];
             h = i;
          }
       }
       if (h != null){
          groups.push({node:h, block:group.slice()});
       }
       var c = 1;
       for ({node:n, block:b} of groups){
           if (n.tagName === 'H1'){
              n.textContent = `${n.textContent} ${h1}`;
              h1++;
           }
           else{
              n.textContent = `${(p === null ? c.toString() : p+'.'+c.toString())} ${n.textContent}`;
           }
           label_headings(b, n.tagName === 'H1' ? null : (p === null ? '':p+'.')+c.toString());
           for (var k of b.filter(function(x){return x.nodeType === 1 && x.tagName[0] != "H"})){
              label_headings(Array.from(k.childNodes).filter(function(x){return x.nodeType === 1}), null);
           }
           c++;
       }
    }
    label_headings(Array.from(root.childNodes).filter(function(x){return x.nodeType === 1}))
}
number_headings(document.querySelector('#text_output'), null)

关于javascript - 对 h1、h2 标题、重置计数器的嵌套文档进行编号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69279236/

相关文章:

JavaScript - 选择单选按钮后删除以前的字段集

javascript - jQuery-File-Upload - 一种形式的多个输入文件

javascript - 如何使用配置有ajax搜索的select2 jquery插件实现选择所有功能?

javascript - 我可以在没有弹出窗口的情况下停止 JS location.href 吗?

java - sun.org.mozilla.javascript.internal.NativeJavaObject 无法转换为 java.lang.String

javascript - SharePoint 的动态 URL 重定向

php - 如何使用 html 电子邮件发送样式

javascript - 选择元素没有 'options' 数组

javascript - 如何让 SocketCluster 在文件更改时重新启动?

javascript - IE 甚至 Chrome 有时不会用 jquery/javascript 填充时间