Nested ordered lists

前端 未结 3 1899
青春惊慌失措
青春惊慌失措 2020-12-06 14:36

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         


        
相关标签:
3条回答
  • 2020-12-06 14:43

    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'});
    
    0 讨论(0)
  • 2020-12-06 14:50

    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)"));
    
    0 讨论(0)
  • 2020-12-06 15:02

    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.org/TR/WCAG10-CSS-TECHS/#lists

    0 讨论(0)
提交回复
热议问题