Обтекание последовательных элементов списка в отдельные группы с использованием jQuery - PullRequest
4 голосов
/ 26 января 2012

У меня есть неупорядоченный список, экспортированный CMS, и мне нужно идентифицировать <li> элементы, имеющие класс .sub, и обернуть их в <ul>.

Я пробовал метод wrapAll(), нокоторый находит все <li class="sub"> элементов и упаковывает их в один <ul>.Мне нужно, чтобы поддерживать отдельные группировки.

Экспортированный код выглядит следующим образом:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li></li>
  <li></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li></li>
 </ul>

Мне нужно, чтобы он был:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <ul>
     <li class="sub"></li>
     <li class="sub"></li>
     <li class="sub"></li>
  </ul>
  <li></li>
  <li></li>
  <li></li>
  <ul>
     <li class="sub"></li>
     <li class="sub"></li>
     <li class="sub"></li>
   </ul>
   <li></li>
   <li></li>
</ul>

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

7 голосов
/ 26 января 2012
  1. Используйте .each для обхода всех элементов .sub.
  2. Игнорируйте элементы, чей родитель имеет класс wrapped, используя hasClass()
  3. Используйте nextUntil(:not(.sub)) для выбора всех последовательных подэлементов (включите себя, используя .andSelf()).Данный первый параметр означает: перестать смотреть вперед, когда элемент не соответствует .sub.
  4. wrapAll

Демо: http://jsfiddle.net/8MVKu/

Для полноты я обернул набор <li> элементов в <li><ul>...</ul></li> вместо простого <ul>.

Код:

$('.sub').each(function() {
   if ($(this.parentNode).hasClass('wrapped')) return;
   $(this).nextUntil(':not(.sub)').andSelf().wrapAll('<li><ul class="wrapped">');
});
$('ul.wrapped').removeClass('wrapped'); // Remove temporary dummy
5 голосов
/ 26 января 2012

Я хотел бы расширить и без того замечательное решение Роба В., предоставляя способ устранения класса временной обертки:

$(document).ready(function() {
    $('li.sub').filter(':not(li.sub + li.sub)').each(function() {
        $(this).nextUntil(':not(li.sub)').andSelf().wrapAll('<li><ul>');
    });
});

http://jsfiddle.net/m8yW3/

Редактировать: Фильтр даже не нужен:

$('li.sub:not(li.sub + li.sub)').each(function() {
    $(this).nextUntil(':not(li.sub)').andSelf().wrapAll('<li><ul>');
});
0 голосов
/ 26 января 2012

Я полагаю, что у вас должен быть этот jQuery:

$('li.sub').wrap('<li><ul>');

Это позволит правильно обернуть ваши <li> элементы в новый тег <ul>, а затем обернуть их внутри <li> теги.Вывод вашего примера будет:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li><ul><li class="sub"></li></ul></li>
  <li><ul><li class="sub"></li></ul></li>
  <li><ul><li class="sub"></li></ul></li>
  <li></li>
  <li></li>
  <li><ul><li class="sub"></li></ul></li>
  <li><ul><li class="sub"></li></ul></li>
  <li><ul><li class="sub"></li></ul></li>
  <li></li>
 </ul>
...