rim89
@rim89
программист-велосипедист

Как обернуть часть списка?

Есть приходящий список, вида:
<ul>
<li class="level-0">link #</li>
<li class="level-1">link #</li>
<li class="level-1">link #</li>
<li class="level-2">link #</li>
<li class="level-2">link #</li>
<li class="level-1">link #</li>
<li class="level-0">link #</li>
<li class="level-0">link #</li>
</ul>

где level-0 - ссылки нулевого уровня, level-1 - первого и level-2 - второго.
Нужно обернуть ссылки первого и второго уровнять тегом UL , чтобы получилось многоуровневое меню:
<ul>
<li class="level-0">link #</li>
<ul class="sub-menu-1">
	<li class="level-1">link #</li>
	<li class="level-1">link #</li>
	<ul class="sub-menu-2">
		<li class="level-2">link #</li>
		<li class="level-2">link #</li>
	</ul>
	<li class="level-1">link #</li>
</ul>
<li class="level-0">link #</li>
<li class="level-0">link #</li>
</ul>

Как сие можно реализовать на jQuery ?
  • Вопрос задан
  • 309 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Рекурсия, конечно же. Функция принимает ul и текущий уровень. Берутся все элементы до следующего с текущим уровнем, оборачиваются в ul, затем следует рекурсивный вызов: свежесозданный ul, текущий уровень + 1.

Например - это если как вы хотели делать, что некорректно, т.к. получается, что ul содержит дочерние ul:

function wrap(ul, level = 0) {
  const
    currLevel = `.level-${level}`,
    nextLevel = `.level-${level + 1}:first`;

  let $li = null;
  while (($li = $(ul).children(nextLevel)).length) {
    const $ul = $('<ul></ul>');
    $ul.append($li.nextUntil(currLevel).addBack().last().after($ul).end());
    wrap($ul, level + 1);
  }
}

Правильно будет добавлять новые ul в li текущего уровня, находящиеся перед элементами следующего уровня:

function wrap(ul, level = 0) {
  const
    currLevel = `.level-${level}`,
    nextLevel = `.level-${level + 1}:first`;

  let $li = null;
  while (($li = $(ul).children(nextLevel)).length) {
    const $ul = $('<ul></ul>');
    $li.prev().append($ul);
    $ul.append($li.nextUntil(currLevel).addBack());
    wrap($ul, level + 1);
  }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
psixodyb
@psixodyb
Хочу, чтобы мой сын стал полубогом Frontend'a
Берешь основной список, идешь по li через .each(function(){});
Внутри функции проверяешь какой сейчас уровень строится(сохраняешь в переменную) и если он увеличился, то открываешь тэг ul, если уменьшился то закрываешь(только открытие и закрытие тэга нужно делать до тэга li который идет в текущем цикле)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы