最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Nested ordered lists - Stack Overflow

programmeradmin3浏览0评论

I need a nested list with subitem numbering, like this:

1. Item 1
  1.1 - Subitem 1
  1.2 - Subitem 2
  1.3 - Subitem 3
  1.4 - Subitem 4
  1.5 - Subitem 5
2. Item 2
  2.1 - Subitem 1
  2.2 - Subitem 2
  2.3 - Subitem 3
  2.4 - Subitem 4
  2.5 - Subitem 5

Well, I know I cannot achieve that with pure HTML. It would be great to use something like this and have the sublist automatically numbered:

<ol>
<li>
   Item 1
   <ol>
     <li>Subitem 1</li>
     <li>Subitem 2</li>
     <li>Subitem 3</li>
     <li>Subitem 4</li>
     <li>Subitem 5</li>
   </ol>
</li>
<li>
   Item 2
   <ol>
     <li>Subitem 1</li>
     <li>Subitem 2</li>
     <li>Subitem 3</li>
     <li>Subitem 4</li>
     <li>Subitem 5</li>
   </ol>
</li>
</ol>

Is there a solution for this using JavaScript or jQuery or something?

I need a nested list with subitem numbering, like this:

1. Item 1
  1.1 - Subitem 1
  1.2 - Subitem 2
  1.3 - Subitem 3
  1.4 - Subitem 4
  1.5 - Subitem 5
2. Item 2
  2.1 - Subitem 1
  2.2 - Subitem 2
  2.3 - Subitem 3
  2.4 - Subitem 4
  2.5 - Subitem 5

Well, I know I cannot achieve that with pure HTML. It would be great to use something like this and have the sublist automatically numbered:

<ol>
<li>
   Item 1
   <ol>
     <li>Subitem 1</li>
     <li>Subitem 2</li>
     <li>Subitem 3</li>
     <li>Subitem 4</li>
     <li>Subitem 5</li>
   </ol>
</li>
<li>
   Item 2
   <ol>
     <li>Subitem 1</li>
     <li>Subitem 2</li>
     <li>Subitem 3</li>
     <li>Subitem 4</li>
     <li>Subitem 5</li>
   </ol>
</li>
</ol>

Is there a solution for this using JavaScript or jQuery or something?

Share Improve this question edited Jun 1, 2012 at 17:06 Gilles 'SO- stop being evil' 108k38 gold badges215 silver badges260 bronze badges asked Dec 5, 2009 at 17:30 Marcos BuarqueMarcos Buarque 3,4188 gold badges46 silver badges47 bronze badges 2
  • While you can't get "dotted hierarchical numbering" like you describe with pure HTML, you can change the numbering style for each level (number, uppercase letter, lowercase letter, greek symbol, etc). And that might be good enough, depending on your need. – jpsimons Commented Dec 5, 2009 at 19:22
  • Thanks, darkporter, I know that, but what I really need is a subnumbered list that carries its parent number and a dot separator. Abraços. – Marcos Buarque Commented Dec 6, 2009 at 3:29
Add a ment  | 

3 Answers 3

Reset to default 8

You can use CSS to do so:

OL { counter-reset: item }
LI { display: block }
LI:before { content: counter(item) ". - "; counter-increment: item }
LI LI:before { content: counters(item, ".") " - "; counter-increment: item }

But it requires support for counter and counters.


Edit    Here’s a jQuery approach similar to dcneiner’s but with no limitation to depth:

function foo($ol, counters) {
    counters = counters || [];
    $ol.each(function(i) {
        var $this = $(this);
        $this.children("li").each(function(i) {
            var $this = $(this);
            $this.prepend(counters.concat([i+1]).join(".") + " ");
            $this.children("ol").each(function(j) {
                foo($(this), counters.concat([i+1]));
            });
        });
    });
}
foo($("ol:not(li > ol)"));

If you want to do it cross-browser with jQuery:

$("ol#list ol").each(function(i, el){
   $(this).children().each(function(ci,cel){
      $(this).prepend('<span class="pseudo-num">' + [i + 1, ci + 1].join('.') + ' </span>');
   });
}).addClass('pseudo-processed');

And in your CSS:

ol .pseudo-num { display: none }
ol.pseudo-processed { list-style: none; padding-left: 0 }
ol.pseudo-processed .pseudo-num { display: inline; font-weight: bold }

This is for one level only. You could alter the code to create a recursive function for multiple levels.

This is setup to progressively enhance your page. Without Javascript it would fallback to normal nested numbering.

UPDATE: Thanks to @Gumbo work, I reworked this code into a recursive plugin. It would use the same CSS as in my previous example, but now it is a "full fledged" jQuery plugin with support for any depth:

$.fn.outline = function(options, counters){
    var options  = $.extend({}, $.fn.outline.defaults, options),
        counters = counters || [];

    this.each(function(){
       $(this).children('li').each(function(i){
           var ct = counters.concat([i + 1]);
           if(counters.length){
             $('<span></span>')
                .addClass(options.numberClass)
                .text(ct.join('.') + ' ')
                .prependTo(this);
           }
           $(this).children('ol').outline(options, ct);
       })
    });

    if(!counters.length) this.addClass(options.processedClass)
}

$.fn.outline.defaults = {
       numberClass: 'pseudo-num',
    processedClass: 'pseudo-processed'
}

You could then call it on a specific #id:

 $("#list").outline();

Or use @Gumbo's nice selector to apply it to all ol tags on one page:

 $("ol:not(li > ol)").outline();

And you can either override the defaults globally, or on an individual basis:

 $.fn.outline.defaults.processedClass = 'ol-ready';
 // or
 $("#list").outline({processedClass: 'ol-ready'});

Neither js nor jquery but CSS:

<STYLE type="text/css">
    UL, OL { counter-reset: item }
    LI { display: block }
    LI:before { content: counters(item, "."); counter-increment: item }
</STYLE>

More here: http://www.w3/TR/WCAG10-CSS-TECHS/#lists

发布评论

评论列表(0)

  1. 暂无评论