Создание вертикального меню аккордеон на jQuery

Использование виджета аккордеон для меню

От автора: в этом уроке мы познакомимся с одним из виджетов библиотеки jQuery UI под названием Accordion (Аккордеон). Чаще всего данный виджет используется для размещения в нем некой блочной связанной информации, что-то сродни с табами. Гораздо реже можно найти использование виджета в качестве меню.

Мы с Вами попытаемся создать функциональное, вертикальное меню аккордеон с помощью одноименного виджета jQuery, которое отлично будет смотреться на сайте.

Итак, приступим…

скачать исходникискачать урок

Использование виджета аккордеон в качестве меню особенно подходит для интернет-магазинов, где в меню категорий практически всегда имеются дочерние категории товаров. Именно поэтому для наших целей мы возьмем готовое меню одного из проектов — интернет-магазин по продаже мобильных телефонов.

Прежде всего определимся с версткой и стилями. Такой будет разметка меню:

Такими будут стили меню:

В итоге мы получим приблизительно следующую картину:

Использование виджета аккордеон для меню

Дочерние категории не скрыты и меню выглядит чересчур громоздко. Вот в этом и заключается идея использования виджета — подпункты должны быть изначально скрыты и открываться должны только при клике на родительской категории. Это первая из задач урока.

Для ее решения подключим виджет. С библиотекой jQuery UI мы уже работали с Вами в ряде предыдущих уроков, а потому далее лишь несколько слов без детальных пояснений. На сайте виджета идем в меню Download, выбираем для скачивания только необходимый нам виджет Accordion, при необходимости выбираем из списка тему оформления виджета или конструируем собственную тему (поскольку оформление меню у нас есть, то я выберу пункт No Theme). После этого жмем кнопку Download и получаем в архиве запрошенное.

В полученном архиве из папки js скопируем 2 файла со скриптами в каталог нашего проекта (у нас это также каталог js). Подключим эти скрипты к документу:

Итак, мы подключили библиотеку jQuery и скрипт виджета. Теперь заставим работать все это. В документации к виджету Вы можете найти описание необходимой разметки, она должна быть следующей: родительские пункты должны быть по умолчанию заголовками H3, дочерние пункты должны быть размещены в блоке и все это вместе также должно быть заключено в блок.

В нашем случае текущая разметка меню также подойдет, у нас: родительские пункты являются заголовками H3, дочерние пункты помещены в список ul, который является блочным элементом, и все меню заключено также в список ul с идентификатором accordion.

Для подключения аккордеона достаточно обратиться к необходимому элементу (у нас это id=»accordion») и вызвать для него метод accordion(). Сделаем это:

В итоге мы получим следующее:

Использование виджета аккордеон для меню

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

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

При клике на раскрытую родительскую категорию дочерний блок не сворачивается… а хотелось бы.

При обновлении страницы не запоминается состояние меню, т.е. если мы имели открытый блок, к примеру, LG, то при обновлении страницы (при переходе на новую страницу) он вновь будет скрыт… это совсем нехорошо.

Итак, давайте их исправлять. Для этого обратимся к документации виджета и воспользуемся двумя свойствами метода accordion — active и collapsible. Второе свойство решит как раз первую проблему, заставив сворачиваться дочерний блок при клике по родителю. Ну а первое свойство отвечает за то, какой блок будет открыт при инициализации аккордеона:

Итак, указав значение свойства collapsible TRUE, мы решили первую проблему. Теперь ко второй. Здесь значением свойства active мы указали 2. Это значение является индексом элемента меню, который необходимо сделать активным (раскрыть). Нумерация начинается с нулевого индекса, и участвуют в ней все недочерние элементы меню. В нашем случае Alcatel имеет индекс 0, Ericsson — 1, LG — 2 и т.д. Таким образом, при инициализации открывается пункт меню LG.

Уже неплохо, но опять же, нет запоминания состояния меню. Если теперь мы раскроем другой пункт меню, то при обновлении опять будет открыт пункт меню LG. Логично, что нам необходимо реализовать следующий алгоритм для решения вопроса:

По клику на родительский (имеющий дочерние) пункт меню мы должны получить и запомнить его индекс.

При инициализации необходимо проверить есть ли значение запомненного нами ранее индекса и, если есть, то сделать такой пункт меню активным, т.е. записать этот индекс значением свойства active.

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

Здесь нам помогут куки. Для решения задачи воспользуемся плагином jquery.cookie, который Вы можете найти в сети или в дополнительных материалах к уроку. Подключаем плагин:

Использование плагина в работе крайне просто. Фактически оно включает в себя всего 3 возможных действия:

установка куки;

чтение куки;

удаление куки.

Итак, давайте создадим куку с именем, к примеру, openItem, и запишем ее значением индекс родительского пункта меню при клике по нему:

Как видите, ничего сложного. Первым параметром метода cookie является имя создаваемой куки, вторым — ее значение. Итак, мы создали куку openItem при клике на родительский пункт меню. В браузерах Chrome или Opera Вы легко можете наблюдать это, кликая по родительским пунктам меню и обновляя страницу. Замечание! В браузере Chrome скрипт будет работать только на сервере.

Кука у нас есть, но пока что она не используется нами… исправим это:

Мы проверяем перед инициализацией меню есть ли что-то в куке openItem. Если условие выполняется, то значение куки мы получаем в одноименную переменную, при этом обязательно приводя значение к числовому типу (по умолчанию тип строковый). Дело в том, что значение опции active обязательно должно быть числового типа.

Отлично! Теперь состояние меню запоминается. При обновлении страницы открытый пункт меню остается открытым. Но если теперь кликнуть по пункту без дочерних элементов — открытый пункт свернется, так и должно быть… но при обновлении он опять разворачивается. Это потому, что кука есть и никуда не пропадает. Исправим сей нюанс, удаляя куку по клику на самостоятельный пункт меню:

Вот теперь все отлично и работает практически так, как нам и хотелось… почему практически? Сейчас в меню первым пунктом идет самостоятельный пункт. Давайте сделаем первым пунктом родительский пункт, например LG.

И что мы видим? После обновления страницы пункт LG стал активным. Это при том, что значением куки мы видим false:

Использование виджета аккордеон для меню

Как же так? Если в условие приходит false, то оно не должно выполняться. На самом деле это не булево FALSE, а строка. Поэтому, чтобы все работало, немного допишем условие и заодно создадим изначально переменную openItem с каким-либо значением, отличным от натурального числа и нуля:

Теперь осталось решить несколько последних нюансов. Попробуйте сейчас кликнуть по дочернему элементу. После клика по нему кука удаляется, соответственно, состояние меню не запоминается. Происходит так потому, что дочерние элементы являются также элементами списка, как и самостоятельные пункты меню. Давайте немного изменим отбор элементов, для которых будем отслеживать событие клика. Выберем только прямых потомков блока с идентификатором accordion:

Вот теперь кука удаляется только при клике по самостоятельным пунктам меню.
Следующим своеобразным багом, который необходимо исправить, является то, что при клике по самостоятельному пункту меню не происходит переход по его ссылке. Это потому, что скрипт виджета блокирует дефолтное поведение ссылки.

Решить эту проблему можно следующим образом – получим ссылку элемента, по которому был клик, и воспользуемся объектом window.location для перехода по этой ссылке:

И, наконец, добавим еще пару опций в метод accordion():

Опция header позволяет явно указать на элемент, который будет заголовком секций. Эту опцию мы указали для решения возможных проблем с IE, в 7-ой версии которого я наблюдал проблемы с аккордеоном. После указания этой опции, проблемы решились.

Вторая опция – autoHeigth со значением false – позволяет решить проблему с высотой открывающихся блоков. По умолчанию значение этой опции выставлено в true, что задает одинаковую высоту для всех скрытых блоков. Значение высоты берется из расчета максимальной высоты блока, т.е. если у одного блока, к примеру, будет 5 пунктов и высота 100 пикселей, то второй блок со всего 1 пунктом будет также иметь высоту 100 пикселей. Появится пустое место у второго блока, что не очень хорошо.

Вот теперь действительно все. Наше вертикальное меню аккордеон, работает так, как и было задумано. В итоге мы получили меню, которое идеально подойдет для категорий интернет-магазина или просто для сайта, где есть разделы с подкатегориями. При этом наше меню еще и «умеет» запоминать свое состояние.

На этом урок закончен. Удачи Вам и до новых встреч!

Метки: , ,

Похожие статьи:

Комментарии Вконтакте:

Комментарии (98)