【问题标题】:Programatically number <h1-h6> with jQuery function使用 jQuery 函数以编程方式编号 <h1-h6>
【发布时间】:2020-08-14 00:14:30
【问题描述】:

我正在尝试创建一个为标题 (h1-h6) 创建自动编号的 javascript 函数(我可以在多个项目中重复使用)。

我目前可以通过 css 使用以下方法:

body { counter-reset: h1; }
h1 { counter-reset: h2; }
h2 { counter-reset: h3; }
h3 { counter-reset: h4; }
h4 { counter-reset: h5; }
h5 { counter-reset: h6; }

h1:before {
    content: counter(h1,decimal) ". ";
    counter-increment: h1;
}
h2:before {
    content: counter(h1, decimal) "." 
             counter(h2, decimal) ". ";
    counter-increment:h2;
}
h3:before {
    content: counter(h1, decimal) "." 
             counter(h2, decimal) "."
             counter(h3, decimal) ". "
    counter-increment:h3;
}
h4:before {
    content: counter(h1, decimal) "." 
             counter(h2, decimal) "."
             counter(h3, decimal) "."
             counter(h4, decimal) ". ";
    counter-increment:h4;
}
h5:before {
    content: counter(h1, decimal) "." 
             counter(h2, decimal) "."
             counter(h3, decimal) "."
             counter(h4, decimal) "."
             counter(h5, decimal) ". ";
    counter-increment:h5;
}
h6:before {
    content: counter(h1, decimal) "." 
             counter(h2, decimal) "."
             counter(h3, decimal) "."
             counter(h4, decimal) "."
             counter(h5, decimal) "." 
             counter(h6, decimal) ". ";
    counter-increment:h6;
}

创建了这种格式:

1. Heading number 1
1.1. Heading level 2
1.1.1. Heading level 3

2. Heading number 2
3. Heading number 3
2.1. Heading level 2
2.2. Heading level 2
2.2.1. Heading level 3

但我想将其转换为 JS 函数(并删除 CSS 药水),以便在某些页面上我可以拥有:

if( typeof mbopts !== 'undefined' && mbopts.length > 0 ) {
    var mbopts = {
        levels:    Int,     // [1-6 being H1-H6]
        separator: String,  // decimal, hyphen, brace -> .,)
        startAt:   Int,     // default: 1, but what the begin numbering at
    };
}
$('#main').mbheaders(mbopts);

然后在函数中:

(function(h) {
    h.fn.mbheaders = function( mbopts ) {
        // create the defaults
        let mbdefaults = {
            levels: 6,
            separator: "decimal",
            startAt: 1
        };

        // extend the defaults
        let mboptions = h.extend( {}, mbdefaults, mbopts );


        return this.each( function() {

            // the variable for this
            var $this = h(this);
            
            // do the magic
            // 
            // get $levels and use that as the limiter
                // 1. find all the H1 in the scope
                // 1.1. add the start number to it
                // 
                // 2. find all the H2 under H1 until next H1
                // 2.1. add the (H1 + index++) to it
                // 
                // ...
                // 
                // 6. find all the H6 under H5 until next H6
                // 6.1. add the (H1 + H2 + H3 + H4 + H5 + index++) to it
        }
    }
}( jQuery ));

我想这样做的原因是,当我编写文档时,我有一个整页文档 (full.md),但我也将各个部分拆分为它们自己的文件 (01-section.md02-section.md 等)。问题是当文件从02-section.md 开始时,标题重新编号为1. 而不是变量。


html 处理时的示例.md 文件

<article class="markdown-section" id="main">
    <h1 id="about-this-document">About this document</h1>
    <p>This is the online documentation of the <strong>Company Procedures</strong>.</p>

    <h1 id="everyone">Everyone</h1>

        <h2 id="logging-into-your-computer">Logging into your computer</h2>
            <p>These are the instructions on how to log into your computer.</p>

        <ol>
            <li>Step one</li>
            <li>Step two</li>
        </ol>

        <h2 id="programmes-on-taskbar">Programmes on taskbar</h2>

            <h3 id="microsoft-word">Microsoft Word</h3>
                <p>This is a word processor</p>

            <h3 id="mail">Mail</h3>
                <p>This is for your emails</p>

            <h3 id="document-management">Document management</h3>
                <h4 id="windows-explorer">Windows Explorer</h4>
                <h4 id="xyplorer">XYPlorer</h4>

    <h1 id="special-areas">Special areas</h1>

        <h3 id="on-the-road">On the road</h3>
        <h3 id="remote">Remote</h3>

</article>

以及对这个问题很重要的输出:

1. Everyone
1.1. Logging into your computer
1.2. Programmes on taskbar
1.2.1. Microsoft Word
1.2.2. Mail
1.2.3. Document management
1.2.3.1. Windows Explorer
1.2.3.2. XYPlorer

2. Special areas
2.1.1. On the road
2.1.2. Remote

【问题讨论】:

  • 如果你是jQuery.fn.extending,为什么还要使用 CSS?使用循环很容易创建增量。
  • @StackSlave 抱歉,我不清楚!我想用 JS 替换 CSS - 但 CSS 是我想用 JS 函数实现的 - 只是我不知道如何将 h1 匹配到 h1 然后循环所有 h2 里面等等。
  • 将有助于根据minimal reproducible example 提供标记示例。如果每组标题都包含在父容器中,您可以遍历这些容器并使用索引来确定起始编号
  • @charlietfl 我已经用md 的示例更新了问题,该示例将用作源
  • 为什么提供markdown而不是html? JS 将用于生成的 html。痛苦转换只是为了测试你的插件代码

标签: javascript html jquery css function


【解决方案1】:

这并不完美,需要进一步开发以考虑具有不同标题变体的部分,但应该为您提供一个良好的起点

使用nextUntil() 它将h1 组包装在一个部分中,然后循环遍历这些部分以将其索引用作主要编号,然后循环遍历h2 以获取次要编号等

// wrap all h1 in a section
$('h1').each(function() {
  $(this).nextUntil('h1').add(this).wrapAll('<section>');
});
// loop over sections after first one
$('section:gt(0)').each(function(i) {
  const num = i + 1, $sect = $(this);
  $sect.find('h1').prepend(`${num} `);
  $sect.find('h2').each(function(i) {
    const subnum = i + 1;
    $(this).text(function(_, txt) {
      return `${num}.${subnum} ${txt}`
    });

    $(this).nextUntil('h2', 'h3').text(function(i, txt) {
      return `${num}.${subnum}.${i+1} ${txt}`
    });
  });
});
section { border: 2px solid #ccc}
h1 {color: red}
h2 {color: blue}
h3 {color: green}
h1,h2,h3,h4,p{margin:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<article class="markdown-section" id="main">
  <h1 id="about-this-document">About this document</h1>
  <p>This is the online documentation of the <strong>Company Procedures</strong>.</p>

  <h1 id="everyone">Everyone</h1>

  <h2 id="logging-into-your-computer">Logging into your computer</h2>
  <p>These are the instructions on how to log into your computer.</p>

  <ol>
    <li>Step one</li>
    <li>Step two</li>
  </ol>

  <h2 id="programmes-on-taskbar">Programmes on taskbar</h2>

  <h3 id="microsoft-word">Microsoft Word</h3>
  <p>This is a word processor</p>

  <h3 id="mail">Mail</h3>
  <p>This is for your emails</p>

  <h3 id="document-management">Document management</h3>
  <h4 id="windows-explorer">Windows Explorer</h4>
  <h4 id="xyplorer">XYPlorer</h4>

  <h1 id="special-areas">Special areas</h1>

  <h3 id="on-the-road">On the road</h3>
  <h3 id="remote">Remote</h3>

</article>

【讨论】:

    【解决方案2】:

    我刚刚为jQuery 创建了一个.ol() 方法。它创建一个有序列表并返回一个具有.li() 方法的构造函数的new 实例。 .li() 方法返回对有序列表的引用。列出来!

    function Ol(j){
      const ol = $('<ol></ol>');
      j.append(ol);
      this.li = (title, noIncrement = false)=>{
        let n = noIncrement ? '' : ' '+(ol.children().length+1);
        let li = $('<li>'+title+n+'</li>');
        ol.append(li);
        return li;
      }
    }
    $(function(){
    $.fn.extend({
      ol:function(){
        return new Ol(this);
      }
    });
    const test = $('#test'), titles = test.ol(), title1 = titles.li('Title'), sections = title1.ol();
    for(let i=0,l=10; i<l; i++){
      for(let n=0,chapters=sections.li('Chapter').ol(),q=4; n<q; n++){
        for(let z=0,subs=chapters.li('Section').ol(),c=3; z<c; z++){
          subs.li('sub-section').ol().li('content would go here', true);
        }
      }
    }
    const title2 = titles.li('Title').ol(), chapter1 = title2.li('Chapter').ol();
    const chapter2 = title2.li('Chapter').ol(), chap1Sec1 = chapter1.li('Section').ol();
    const chap2Sec1 = chapter2.li('Section').ol();
    chap2Sec1.li('sub-section'); chap2Sec1.li('sub-section');
    chap1Sec1.li('sub-section').ol().li('This is how you might use outside a loop', true);
    });
    *{
      margin:0; padding:0;
    }
    ol{
      list-style:none;
    }
    ol li{
      margin-left:10px;
    }
    #test>ol>li{
      margin-left:0;
    }
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
    <div id='test'></div>

    【讨论】:

      猜你喜欢
      • 2011-07-04
      • 1970-01-01
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      相关资源
      最近更新 更多