嵌套有序列表

3
我需要一个嵌套列表,其中包含子项目编号,就像这样:
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

我知道单纯使用HTML无法实现这一点。如果能使用类似以下的东西并自动编号子列表,那就太好了:

<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>

有没有使用JavaScript或jQuery或其他工具的解决方案?

虽然您无法通过纯HTML获得像您描述的“点分层编号”,但您可以为每个级别更改编号样式(数字、大写字母、小写字母、希腊符号等)。这可能已经足够了,具体取决于您的需求。 - jpsimons
谢谢,darkporter,我知道这个,但我真正需要的是一个带有父编号和点分隔符的子编号列表。抱抱。 - Marcos Buarque
3个回答

8
您可以使用 CSS 来实现:
OL { counter-reset: item }
LI { display: block }
LI:before { content: counter(item) ". - "; counter-increment: item }
LI LI:before { content: counters(item, ".") " - "; counter-increment: item }

但是它需要支持 countercounters


编辑    这里有一个与dcneiner类似但没有深度限制的jQuery方法:

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)"));

谢谢!我选择了上面那个,因为它具有跨浏览器兼容性。谢谢。 - Marcos Buarque
像重构一样...我现在要尝试重写你的代码了...你给了我灵感... - Doug Neiner
好的,我采用了你代码的基本思路(喜欢使用concat复制数组并添加数字!),并将其转化为了一个jQuery插件。现在已经放在我的答案中了。感谢你花时间改进它! - Doug Neiner
@Marcos Buarque:我不明白为什么他的第一个版本比我的更具有跨浏览器兼容性。 - Gumbo
哎呀,第一次您发的是纯 CSS。我错了吗?无论如何,非常感谢您的帮助... - Marcos Buarque
@Marcos Buarque:是的,没错。然后我加入了受到dcneiner第一种方法启发的jQuery示例。 - Gumbo

6
如果你想用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');

在你的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 }

这仅适用于单层级。您可以更改代码以创建适用于多层级的递归函数。

这是为了逐步增强您的页面而设置的。如果没有Javascript,它将回退到正常的嵌套编号。

更新:由于@Gumbo的工作,我将此代码重新制作成递归插件。它将使用与先前示例中相同的CSS,但现在它是一个“全功能”的jQuery插件,支持任何深度:

$.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'
}

您可以在特定的#id上调用它:
 $("#list").outline();

或者使用 @Gumbo 的优秀选择器将其应用于页面上的所有 ol 标签:
 $("ol:not(li > ol)").outline();

你可以全局或个别地覆盖默认设置:

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

嘿,谢谢,这个方法确实有效!由于浏览器对纯CSS解决方案的支持不足,因此JavaScript解决方案仍然更好。 - Marcos Buarque
嘿,谢谢,这真的很有帮助(多层代码重写)。我想知道其他网站管理员是否有同样的需要这种列表...我相信是的。抱抱。 - Marcos Buarque

4

不是js也不是jquery,而是CSS:

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

更多信息请参考: http://www.w3.org/TR/WCAG10-CSS-TECHS/#lists

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接