За основу, на сей раз, возьмем код, рассмотренный в статье "Аккордеон без списков ". Как и в прошлый раз, набросаем план того, что необходимо сделать с учетом особенностей разметки меню:
1. Добавить маркеры только к заголовкам, которые имеют соседние скрытые блоки.
2. Показывать только один скрытый блок. При клике на следующем заголовке, текущий активный блок должен прятаться.
3. Маркеры должны менять отображение в зависимости от того, видим ли блок в настоящий момент, или скрыт.
Одним словом, сделать точно такое же меню, как и рассмотренное в статье "Расширяем функциональность аккордеона", только использовать теперь другую разметку.
Сначала добавим маркеры. В прошлый раз мы проверяли, есть ли у пункта меню дочерний элемент ul и если таковой был, добавляли этому пункту конструкцию <span> </span>. В этот раз роль пунктов верхнего меню у нас выполняют заголовки h3 и единственными их дочерними элементами являются элементы a. Роль субменю выполняют блоки с классом sub_nav и расположены они по соседству с заголовками, т.е. являются сестринскими элементами. Соответственно, в этот раз нам нужно добавить маркеры только к тем заголовкам, у которых следующим элементом будет блок sub_nav.
Выполнить это немного сложнее, чем кажется на первый взгляд. Сначала нужно отобрать в набор все блоки с классом sub_nav, а затем добавить конструкцию <span> </span> элементам, находящимся перед отобранными блоками. Вот как должна выглядеть строка кода, выполняющая нужное действие.
$('div.nav_wrap h3').next('.sub_nav').prev().append('<span> </span>');
Ну и поскольку мы уже в прошлый раз начали использовать переменные, то и в этот раз не будем от них отказываться. Итоговый фрагмент кода у меня теперь выглядит так:
$(function () { var el = $('div.nav_wrap h3'), prevElement = el.next('.sub_nav').prev(); prevElement.append('<span> </span>'); });
Стили для спанов ничем не будут отличаться, меняются лишь селекторы, к которым нужно применить те же правила:
.nav_wrap h3 { position:relative; } .nav_wrap h3 span { width:0; height:0; position:absolute; top:9px; right:9px; border-top:5px solid transparent; border-bottom:5px solid transparent; border-left:10px solid #000; } .nav_wrap h3.active span { border-top:10px solid #000; border-left:5px solid transparent; border-right:5px solid transparent; }
Первый этап выполнен. Теперь напишем код для скрытых блоков и обозначим поведение спанов. Будем отслеживать клик на заголовках, проверять, является ли блок sub_nav видимым и если нет, то покажем его, а заголовку, находящемуся перед блоком добавим класс active. Соответственно, если блок sub_nav открыт, будем его прятать и убирать класс active с заголовка, находящегося перед блоком. Вот как должен выглядеть итоговый код:
$(function () { var el = $('div.nav_wrap h3'); prevElement = el.next('.sub_nav').prev(); prevElement.append('<span> </span>'); el.click(function() { var checkElement = $(this).next('.sub_nav'); visibleElement = $('div.sub_nav:visible'); visibleElement.stop().animate({'height':'toggle'}, 500).prev().toggleClass('active'); if((checkElement.is('div.sub_nav')) && (!checkElement.is(':visible'))) { checkElement.stop().animate({'height':'toggle'}, 500).prev().toggleClass('active'); } return false; }); });
Задача выполнена и нас уже не подловишь на разных html разметках - мы способны справиться с любой. Демонстрируем работу, прячем в карман очередную пачку премиальных и ... выслушиваем новое пожелание. На глаза руководителю попался слайдер изображений, расположенный на главной странице сайта конкурентов. Картинки плавно появлялись и исчезали, меняя друг друга.
Само собой на нашем сайте требуется сделать так же. Не будем пугаться новой задачи. Мы ведь уже не зеленые новички и способны изобрести нечто подобное. В следующей статье обсудим, как написать свой первый слайдер изображений...
Конечный результат примера аккордеона без использования списков качаем, если потребуется, по ссылке ниже.