Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Как обрамить несколько элементов в ul (https://javascript.ru/forum/jquery/9664-kak-obramit-neskolko-ehlementov-v-ul.html)

Alexxx 30.05.2010 22:37

Как обрамить несколько элементов в ul
 
Суть задачи:
Обрамить пункты меню в UL для того, что бы меню росло не в высоту, а в ширину т.е. образовывались столбцы.

Исходный HTML

<ul class="menu">
<li><a href="#">Angelo Cappellini</a></li>
<li><a href="#">Antico Borgo</a></li>
<li><a href="#">Arca</a></li>
<li><a href="#">Asnaghi Interiors</a></li>
<li><a href="#">Bastex</a></li>
<li><a href="#">BM Style</a></li>
<li><a href="#">Caroti</a></li>
</ul>


И в итоге с помощью Jquery я хочу получить такое преобразование:

<ul class="menu">
<li><a href="#">Angelo Cappellini</a></li>
<li><a href="#">Antico Borgo</a></li>
<li><a href="#">Arca</a></li>
<li><a href="#">Asnaghi Interiors</a></li>
</ul>
<ul class="menu">
<li><a href="#">Bastex</a></li>
<li><a href="#">BM Style</a></li>
<li><a href="#">Caroti</a></li>
</ul>


Получилось, что меню разбивается на каждой четвертой по счету ссылке (li), таким образом при добавлении новых ссылок в меню - оно будет образовывать новые колонки и они будут выстраиваться по горизонтали (CSS).

Пытался делать так:
$(function() {
    $('ul.menu li:eq(4)').after('</ul>' + '<ul class="menu">'); 
});


Но далее знаний не хватает, а поиск дал больше вопросов, че ответов =(


Благодарю)

micscr 31.05.2010 08:16

пробегаешь по li и формируешь в переменной новый список из ul. А потом существующий заменишь на получившийся.

exec 31.05.2010 08:58

$('ul.menu li').each(function (i) {
	if (i % 4 == 3) {
		$(this).after('</ul><ul class="menu">');
	}
});

sysya 31.05.2010 10:12

Цитата:

Сообщение от exec (Сообщение 57153)
$('ul.menu li').each(function (i) {
	if ((i % 4 == 3) {
		$(this).after('</ul><ul class="menu">');
	}
});

Скобочка в условии, ошибка.
А в условии сказано, что после 12 элемента добавить </ul><ul class="menu"> ? Или мне мануальчик перечитать надо?

Alexxx 31.05.2010 10:16

Цитата:

Сообщение от exec (Сообщение 57153)
$('ul.menu li').each(function (i) {
	if ((i % 4 == 3) {
		$(this).after('</ul><ul class="menu">');
	}
});

Наверное, корректнее так:

$(function() {
$('ul.menu li').each(function (i) {
	if (i % 4 == 3) {
		$(this).after('</ul><ul class="menu">');
	}
});
});


Спасибо!

Alexxx 31.05.2010 10:23

На выходе получаю некорректный HTML

<ul class="menu">
<li><a href="#">Angelo Cappellini</a></li>
<ul class="menu"></ul>
<li><a href="#">Antico Borgo</a></li>
<li><a href="#">Arca</a></li>
<li><a href="#">Asnaghi Interiors</a></li>
<li><a href="#">Bastex</a></li>
<ul class="menu"></ul>
<li><a href="#">BM Style</a></li>
<li><a href="#">Caroti</a></li>
<li><a href="#">Caspani Tino</a></li>
</ul>


Вероятно, что Jquery переставляет местами </ul> и <ul class="menu"> дабы исправить "ошибку".

micscr 31.05.2010 10:24

Работает что ли так? А если у родителя hlml() посмотреть?

micscr 31.05.2010 10:25

Цитата:

Сообщение от Alexxx (Сообщение 57156)
На выходе получаю некорректный HTML

делай как я тебе говорил (я у себя проверял в работе).

Alexxx 31.05.2010 10:36

Цитата:

Сообщение от micscr (Сообщение 57158)
делай как я тебе говорил (я у себя проверял в работе).

Я в Jquery небельмес =) Только только начал изучать... Логику понял, но код реализовать с ходу точно пока не смогу, поэтому и прошу помощи тут.

micscr 31.05.2010 10:47

За готовым кодом - в раздел работа, там за пару баксов сделают.

А тут попрошу потрудиться самому иначе не будет толка.
Алгоритм уточню:
1) создаем контейнер накопления
2) пробегаем по li существующего при этом каждые 4-е запихиваем в отдельный ul
3) эти отдельные ul добавляем в контейнер
4) вместо исходного списка вставляем контейнер

Используются только широко распространенные методы jQuery. Жду попыток. :)

B@rmaley.e><e 31.05.2010 10:53

$('ul.menu').each(function(){
  $('<ul class="menu"></ul>').append($('li:gt(4)', this)).insertAfter(this);
});

Alexxx 31.05.2010 10:58

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 57164)
$('ul.menu').each(function(){
  $('<ul class="menu"></ul>').append($('li:gt(4)', this)).insertAfter(this);
});

Да, работает, спасибо за подсказку, но дело в том, что li:gt(4) обрамляет не каждые 4 пункта меню, а первые 4 и все остальные (а их может быть много). Поэтому получается, что такой вариант корректно работает с меню до 8 пунктов.

Alexxx 31.05.2010 10:58

Цитата:

Сообщение от micscr (Сообщение 57161)
За готовым кодом - в раздел работа, там за пару баксов сделают.

А тут попрошу потрудиться самому иначе не будет толка.
Алгоритм уточню:
1) создаем контейнер накопления
2) пробегаем по li существующего при этом каждые 4-е запихиваем в отдельный ul
3) эти отдельные ul добавляем в контейнер
4) вместо исходного списка вставляем контейнер

Используются только широко распространенные методы jQuery. Жду попыток. :)

Буду пытаться. Хотя даже не знаю как сделать 1 пункт))

micscr 31.05.2010 11:03

Цитата:

Сообщение от Alexxx (Сообщение 57166)
Буду пытаться. Хотя даже не знаю как сделать 1 пункт))

$ulist = $('<div></div>');

x-yuri 31.05.2010 11:36

Цитата:

Сообщение от Alexxx
Я в Jquery небельмес

если ты в javascript бельмес, вопросов быть не должно

Цитата:

Сообщение от Alexxx
Буду пытаться. Хотя даже не знаю как сделать 1 пункт))

задавай вопросы

exec 31.05.2010 11:48

Есть ещё такой вариант:

var num = 3; // кол-во четвёрок <li>
for (var i = 0; i <= num; i++) {
	$('ul.menu li:lt(' + (i * 4) + '):gt(' + (i * 4 + 3) + ')').wrapAll('<ul class="menu"></ul>')
}

micscr 31.05.2010 12:08

Цитата:

Сообщение от exec (Сообщение 57174)
Есть ещё такой вариант:

var num = 3; // кол-во четвёрок <li>
for (var i = 0; i <= num; i++) {
	$('ul.menu li:lt(' + (i * 4) + '):gt(' + (i * 4 + 3) + ')').wrapAll('<ul class="menu"></ul>')
}

проверял? А то у меня ничего не происходит(потому что коллекции пустые).

B@rmaley.e><e 31.05.2010 12:09

Цитата:

Сообщение от exec
var num = 3; // кол-во четвёрок <li>

Ужас. А вычислить нельзя?

micscr 31.05.2010 12:24

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 57179)
Ужас. А вычислить нельзя?

а зачем ему мучаться? Главное же побыстрей свой новый вариант продемонстрировать :blink: . А работает, не работает ...

x-yuri 31.05.2010 12:30

Цитата:

Сообщение от micscr
проверял? А то у меня ничего не происходит(потому что коллекции пустые).

хотя казалось бы, такой ник... мог бы и проверить :)

B@rmaley.e><e 31.05.2010 12:33

$('ul.menu').each(function(){ 
	var li = $('li',this), length = Math.ceil(li.length / 4), i = 0, uls = $('<div></div>');

	for(; i < length; i++){
		$('<ul class="menu"></ul>').append(li.filter(':gt(' + (i*4-1) + ')').filter(':lt(' + (i+1)*4 + ')')).appendTo(uls); 
	}
	$(this).replaceWith(uls.children());
});
Или элегантней, но не оптимально:
$('ul.menu').each(function(){ 
	var i = Math.ceil($('li',this).length / 4), uls = $('<div></div>');

	while(i--) $('<ul class="menu"></ul>').append($('li',this).filter(':lt(4)')).appendTo(uls); 
	$(this).replaceWith(uls.children());
});

Alexxx 31.05.2010 15:17

Спасибо! Сравнив со своими потугами, понял, что пытался делать проще, но не получил бы рабочего кода.


Часовой пояс GMT +3, время: 03:24.