Иерархический список с помощью jQuery

Написал очень простой и функциональный скрипт организации иерархического списка. Но смысл заключается не только в скрипте, но и в правильной вёрстке.

HTML

Вот из такого небольшого обычного списка мы сделаем раскрывающийся иерархический список.

  • Модель статусных групп (классов) Л. Уорнера
    • Высший класс
      • Верхний-высший класс, включал так называемые старые семьи.
      • Низший-высший класс, не включал старые родовые семьи.
    • Средний класс
      • Верхний-средний класс состоял из собственников и профессионалов.
      • Нижний-средний класс составляли низшие служащие, приказчики, клерки.
    • Низший класс
      • Верхний-низший класс включал рабочих.
      • Нижний-низший класс — «социальное дно».

Получится следующее:

  • Модель статусных групп (классов) Л. Уорнера
    • Высший класс
      • Верхний-высший класс, включал так называемые старые семьи.
      • Низший-высший класс, не включал старые родовые семьи.
    • Средний класс
      • Верхний-средний класс состоял из собственников и профессионалов.
      • Нижний-средний класс составляли низшие служащие, приказчики, клерки.
    • Низший класс
      • Верхний-низший класс включал рабочих.
      • Нижний-низший класс — «социальное дно».

Как видите, код лаконичный и логичный.

Что нужно сделать?

  • Каждому элементу списка, который имеет внутренний список, с помощью JS добавим тэг <span>, который будет являться кнопкой раскрытия или закрытия списка. Эта кнопка будет текстовой, но нам бы хотелось, чтоб была возможность отображать её и графически. Поэтому для удобства, внутри поместим ещё один тэг, который будет содержать картинку, которую и наложим на текстовое отображение кнопки.
  • Скроем все внутренние списки, пропишем начальные классы.
  • Каждой кнопке напишем событие onclick, по которому будем изменять класс у элемента списка, и скрывать или показывать внутренний список

CSS

ul.ns_hierarchy li{ /* Чтобы не было сдвига элементов списка из-за кнопки раскрытия/закрытия */
	clear: both;
}
ul.ns_hierarchy, ul.ns_hierarchy ul{
	list-style-type: none; /* Убираем маркер */
	margin: 0;
	padding-left: 0px;
}
/* наводим красоту */
ul.ns_hierarchy{
	padding-left: 18px;
}
ul.ns_hierarchy ul{
	padding-left: 22px;
}
li.nsh_closed span, li.nsh_opened span{ // тэг span, на который будем жать
	float: left;
	position: relative;
	width: 9px;
	height: 9px;
	margin: 6px 6px 0 -18px;
	cursor: pointer;
	overflow: hidden;
	font: normal 0.8em/0.8em sans-serif;
}
li.nsh_closed span em, li.nsh_opened span em{ // тэг em в тэгу span, который будет содержать картинку
	position: absolute;
	width: 9px;
	height: 9px;
	top: 0;
	left: 0;
	background: url(plus-min.gif) no-repeat;
}
li.nsh_closed span em{
	background-position: bottom;
}

Подготовительные работы провели, теперь за дело

jQuery

Не забываем подключить два файла: jquery библиотеку и наш скрипт

А скрипт будет такой:

$(document).ready(function() //загрузив документ,
{
	// добавляем тэг span с плюсиком и тэгом em во все элементы списка,
	// которые содержат внутренние списки
	$("ul.ns_hierarchy li:has(ul)").prepend("+");
	$("ul.ns_hierarchy li:has(ul)").addClass("nsh_closed"); // им же добавляем класс по-умолчанию
	$("ul.ns_hierarchy li > ul").hide(); // скрываем все внутренние списки
	// при щелчке по кнопке меняем плюс на минус, или наоборот,
	// а так же скрываем или показываем внутренние списки
	$("ul.ns_hierarchy li > span").click(function()
	{
		if( $(this).parent("li").attr("class") == "nsh_closed" )
		{
			$(this).parent("li").attr("class", "nsh_opened");
			$(this).html("−");
			$(this).next("ul").show();
		}
		else if( $(this).parent("li").attr("class") == "nsh_opened" )
		{
			$(this).parent("li").attr("class", "nsh_closed");
			$(this).html("+");
			$(this).next("ul").hide();
		}
	});
});

Вот и всё.

По желанию можно изменить внешний вид, заменить изображение кнопки, изменить скрипт так, чтобы он не скрывал/показывал списки напрямую, а менял классы, этим можно добавить возможность прописывания классов перед загрузкой меню, чтобы с самого начала меню уже было открыто.

Скрипт кроссбраузерный, расширяемый, поключаемый, настраиваемый и прочее и прочее…
Пользуйтесь!

Посмотреть пример

Скачать исходник

Дата: 02.01.2008
»
Категории: CSS | JavaScript
Google     

]]> deni2s ]]>

V obshem to i v javascript takoje netrudno napistj, chtob biblioteku jquery ne prishlosj podkljuchatj.

»

]]> Никита ]]>

Можно, но так быстрее и меньше кода писать. Тем более jQuery может использоваться на одном сайте и для других целей.

»

]]> zigmat ]]>

Наверное круто…

»

]]> Danaki ]]>

А ты попробуй это на большом количестве элементов да на Интернет Эксплорере. Я в своем gate.lv тоже пытался подобным образом сделать, только задача была сэкономить размер загружаемой страницы. В результате, на моих 1000-ах span это рендерилось полминуты. JS на IE очень сильно медленный, пришлось тупо настроить compress и забыть.

»

]]> Никита ]]>

Я думаю, это логично, что данный скрипт применим для небольшого списка. Для больших списков нужно генерировать кнопки серверным скриптом.

»

]]> Максим Покровский ]]>

Спасибо за подробное комментирование кода )
Очень полезно

»

]]> Андрей ]]>

Отлично. Как раз для украшения сойдет. Спасибо.

»

]]> Все о jquery на одной странице :: TermiT’s Blog ]]>

[...] Иерархический список с помощью jQuery [...]

»

]]> zt50 ]]>

Вот такой вопрос — а как сделать так чтобы при клике выделялся элемент, а остальные погасали?

»

]]> Никита ]]>

zt50, Разве что заменять класс у всех элементов

»

]]> zt50 ]]>

Никита: а как это сделать? танцы с бубном с each на пользу не пошли. У меня в каждом li стоит some_text, скрипт $(‘#tree_title’).css(‘color’,'#ff00ff’); работает только на первый элемент :(

»

]]> tviggy ]]>

А почему при работе с ссылками нечего не работает?

»

]]> Никита ]]>

zt50, конечно срабатывает на первом элементе, поскольку #tree_title это id, а он должен быть уникальный. Используйте классы.

tviggy, не понял вопроса.

»

]]> tviggy ]]>

Я имею виду, что если между тегами

Модель статусных групп (классов) Л. Уорнера

Высший класс

прописать не текст, а ссылки

“>Модель статусных групп (классов) Л. Уорнера

Высший класс

то раскрывающийся иерархический список не работает :(

»

]]> tviggy ]]>

Я имею виду, что если между тегами
(ul class=”ns_hierarchy”)
(li)Модель статусных групп (классов) Л. Уорнера
(ul)
(li)Высший класс

прописать не текст, а ссылки

(ul class=”ns_hierarchy”)
(li)(a href=”index.php”)Модель статусных групп классов Л. Уорнера(/a)
(ul)
(li)Высший класс

то раскрывающийся иерархический список не работает :(

»

]]> Никита ]]>

tviggy, да, действительно есть такая проблема. Попробую разобраться когда будет время.

»

]]> vilka ]]>

чисто для ссылок вот для такой конструкции:

<a href=”#1″ rel=”nofollow”>Модель статусных групп (классов) Л. Уорнера</a>

<a href=”#1″ rel=”nofollow”>Высший класс</a>
…………………

добавим .next() :
$(this).next().next(“ul”).show();
$(this).next().next(“ul”).hide();

в итоге скрипт станет таким:

$(document).ready(function()
{
$(“ul.ns_hierarchy li:has(ul)”).prepend(“+“);
$(“ul.ns_hierarchy li:has(ul)”).addClass(“nsh_closed”);
$(“ul.ns_hierarchy li > ul”).hide();
$(“ul.ns_hierarchy li > span”).click(function()
{
if( $(this).parent(“li”).attr(“class”) == “nsh_closed” )
{
$(this).parent(“li”).attr(“class”, “nsh_opened”);
$(this).html(“−“);
$(this).next().next(“ul”).show();
}
else if( $(this).parent(“li”).attr(“class”) == “nsh_opened” )
{
$(this).parent(“li”).attr(“class”, “nsh_closed”);
$(this).html(“+“);
$(this).next().next(“ul”).hide();
}
});
});

»

]]> vilka ]]>

alert(‘афтар жжот))) ‘)

хоть бы отпарсил html тэги…

»

]]> vilka ]]>

а вообще сайт классный..
информативный!
автору 10+!!!

»

Напишите комментарий