Вложенные упорядоченные списки
-
13-09-2019 - |
Вопрос
Мне нужен вложенный список с нумерацией подпунктов, например, так:
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 или чего-то еще?
Решение
Если вы хотите сделать это в кроссбраузерном режиме с помощью 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 это было бы возвращением к обычной вложенной нумерации.
Обновить:Благодаря @Гамбо работая, я переработал этот код в рекурсивный плагин.Он будет использовать тот же 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 для этого:
OL { counter-reset: item }
LI { display: block }
LI:before { content: counter(item) ". - "; counter-increment: item }
LI LI:before { content: counters(item, ".") " - "; counter-increment: item }
Но это требует поддержки для counter
и counters
.
Редактировать Вот подход jQuery, аналогичный подходу dcneiner, но без ограничения глубины:
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)"));
Ни 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