Изучать jquery я начал пару месяцев назад по долгу службы, и очень скоро понял насколько это удобно. Причем не только если разрабатываешь какое-нибудь ajax-приложение, но и в более мелких вещах — таких как простенькие анимации, выпадающие менюшки и тд.
В этой статье я опишу как можно с помощью jquery обычное многоуровневое меню сделать раскрывающимся без правки исходного html-кода. Для этого допустим, что на сайте есть такое меню:
| Меню: | Html-код меню: |
|---|---|
<ul id="my-menu">
<li><a href="#0">Главная</a></li>
<li><a href="#0">О компании</a>
<ul>
<li><a href="#0">История</a></li>
<li><a href="#0">Настоящее</a></li>
<li><a href="#0">Будущее</a></li>
</ul>
</li>
<li><a href="#0">Контакты</a></li>
<li><a href="#0">Продукция</a>
<ul>
<li><a href="#0">Мясные продукты</a>
<ul>
<li><a href="#0">Колбаса</a></li>
<li><a href="#0">Сосиски и сардельки</a></li>
<li><a href="#0">Деликатесы</a></li>
</ul>
</li>
<li><a href="#0">Алкоголь</a>
<ul>
<li><a href="#0">Вино</a></li>
<li><a href="#0">Водка</a></li>
<li><a href="#0">Пиво</a></li>
</ul>
</li>
</ul>
</li>
</ul>
|
Некоторые оставляют корневые ссылки ссылками, но мы так делать не будем. У нас корневые ссылки ("О компании", "Продукция", "Мясные продукты", "Алкоголь") не будут вести ни на какую страницу, при клике по ним будет раскрываться подменю.
Итак, первым делом инициализируем библиотеку jquery.js. Желательно подключать ее в секции <head> документа:
<head> .. <script type="text/javascript" src="jquery.js"></script> </head>
Теперь мы может писать javascript-скрипты. Делать это будем в отдельном js-файле, который прилинкуем аналогично jquery.js. Сразу приведу базовый код:
$(document).ready(function() {
$('ul#my-menu ul').each(function(index) {
$(this).prev().addClass('collapsible').click(function() {
if ($(this).next().css('display') == 'none') {
$(this).next().slideDown(200, function () {
$(this).prev().removeClass('collapsed').addClass('expanded');
});
}else {
$(this).next().slideUp(200, function () {
$(this).prev().removeClass('expanded').addClass('collapsed');
$(this).find('ul').each(function() {
$(this).hide().prev().removeClass('expanded').addClass('collapsed');
});
});
}
return false;
});
});
});
Здесь мы делаем следующие вещи:
Попробуем потыкать на результат:
Мне кажется, когда ты скрываешь, например, подменю "Продукция", и потом раскрываешь его — дочерние подменю должны быть закрытыми независимо от того в каком положении они были раньше. Поэтому добавим в callback-функцию метода slideUp еще такую строчку:
$(this).find('ul').each(function() {
$(this).hide().prev().removeClass('expanded').addClass('collapsed');
});
В принципе, меню готово. Однако можно навесить еще пару небольших примочек. Например, реализовать запоминание раскрытости меню при переходе на другие страницы. Сделаем это через cookie. Смысл таков — когда меню раскрывается, в cookie заносится запись вида 'submenuMark-xx=opened', где xx - порядковый номер (индекс) данного подменю в списке всех подменю. Соответственно, когда закрывается - запись стирается из cookie.
Для работы с cookie нам будет удобен плагин jquery.cookie.js. Скачаем его и подключим рядом с jquery. Теперь напишем пару вспомогательных фукнций для работы с cookie:
function cookieSet(index) {
$.cookie('submenuMark-' + index, 'opened', {expires: null, path: '/'});
}
function cookieDel(index) {
$.cookie('submenuMark-' + index, null, {expires: null, path: '/'});
}
При загрузке документа нам нужно посмотреть какие подменю отмечены в куках и открыть их. Поэтому вставим следующий кусок кода в цикл по всем подменюшкам:
$('ul#my-menu ul').each(function(i) {
.....
if ($.cookie('submenuMark-' + i)) {
$(this).show();
$(this).prev().removeClass('collapsed').addClass('expanded');
}else {
$(this).hide();
$(this).prev().removeClass('expanded').addClass('collapsed');
}
.....
});
Как вы могли заметить, у нас теперь есть CSS-классы 'expanded', 'collapsed' и 'collapsible' — таким образом можно немного приукрасить наше меню с помощью CSS.
И самый последний штрих — везде, где в нашем коде открывается либо закрывается подменю, поставить вызов соответствующей куки-функции. Этого я описывать уже не буду — можно посмотреть в готовом скрипте. Итак, посмотрим на готовое меню:
Сохранение положения меню в cookie можно проверить если потыкать на ссылки и перезагрузить страницу — подменю сохранят свое состояние.
Посмотреть исходники можно в прикрепленном архивчике. Удачи!
| Прикрепленный файл | Размер |
|---|---|
| exp_menu.rar | 17.98 кб |
Комментарии
Спасибо за статью.
Не мог бы ты подсказать как сделать чтобы при открытии одного пункта закрывались другие. Тоесть например если открыт пунт "О компании" и ты нажимаешь на пункт "Продукция" то сворачивается О компании и открывается Продукция.
Конечно могу, всегда рад помочь :)
Скачай http://alt-f4.ru/files/exp_menu1.rar - этот файлик. Там тоже самое, что в прикрепленном к посту, но добавлено несколько строк, отвечающие за закрытие остальных пунктов меню. Добавленный кусок кода находится между 19-ой и 28-ой строками файла submenu_jquery.html
Спасибо большое тебе :)) очень помог) Удачи тебе хороший человек)))
Уважаемый автор! Очень хорошая статья! Только один нюанс! Как сделать чтоб при нажатие на ссылку она оставалась активной (то есть выделялась цветом). Очень буду признателен за помощь.
P.S. За ранее спасибо.
Вы хотите, чтобы после перехода по ссылке в данном меню, на новой странице она выделялась определенным образом?
Если так, то такое можно реализовать, сохраняя дополнительную переменную в куках и потом ее читая, присваивать нужный класс "активной" ссылке.
Я могу помочь вам настроить меню под ваши нужды за небольшую символическую плату. Мои контакты можете найти на странице http://alt-f4.ru/contact
А как оставить корневые ссылки ссылками?
отдельное человеческое..тебе..спасибо)
долго мучался с куками .. но похоже здесь я найду ответ..
А КСТАТИ АВТОР ТЫ ДОПУСТИЛ ОДНУ ГЛУПОСТЬ. Зачем использовать add и remove class итп когда есть toggle class? Он автономно при каждом клике переключаеться в классы.
В IE7 работает коряво! при закрытии подменю оно съезжает в право.
nemo, там проверяется класс в определенном месте.
Имя, по-моему у вас дело в стилях css. у меня все нормально работает.
Добрый день!
А как к этому меню прикрутить информацию? т.е нажимаю я на ссылку и в определенном месте на сайте появляется та или иная инфа.
Есть ли возможность оставить корневые ссылки ссылками? Допустим для реализации содержания книги это достаточно принципиально. А в остальном все просто супер. Огромное спасибо))
Уже нашла! Нужно заменить последнюю строчку!
return true; // Prohibit the browser to follow the link address
Не за что :)
А из-за чего скачет в IE? Как бы исправить...
Решение скачков в ИЕ: вместо .slideUp и .slideDown использовать .animate с соответствующими параметрами.
Добрый день! буду очень признателен за подсказку . Все работает отлично но когда хочу разместить данный код в шаблоне что бы не размещать меню на всех страницах пишет (абсолютное положение 27553).......Содержит ошибку: вложенные области доступные для редактирования. Пожалуйста подскажи в чем дело?
Поясните пожалуйста, в каком шаблоне вы размещаете. Про какую систему идет речь и что выдает ошибку?
Использую программу Dreamweaver, файл шаблона *.dvt, при попытке создать из страници шаблон в етой программе выдается ошибка со следующим текстом например: Строка 571 в столбце 60 (абсолютная ошибка 31400)(далее путь местонахождения файла шаблона)...содержит ошибку: Вложенные области, доступные для редактирования. А если я создаю шаблон на основе выбранного шаблона то все нормально но область в этом вложенном шаблоне приходиться редактировать на каждой строница которая прицеплена к этому файлу:(. Да и еще один вопрос как можно вставить картинку напротив слов в подменю например перед словами "История", "Настоящее" и т д. Заранее СПАСИБО.
Прошу прощение за ошибку (Файл с расширением *. dwt)
Огромный респект за Ваш труд. И за то, что делитесь своими знаниями с остальными. У меня вопрос, не смогла разобраться. Как сделать, чтобы при переходе на другой пункт меню подменю родительского пункта закрывались? В файле menu1.rar подменю закрывается, если только осуществлен переход на пункт с подменю. Если же переход на ссылку верхнего уровня, не имеющую подменю, то подменю остается открытым.
Например: если открыт пункт "О компании", а нажимаешь на "Главная", то пункт "О компании" закрывается.
СПасибо!
Вот зашел на сайт, спасибо гуглю, нашел решения моим вопросам за 10 минут, сайт пошел сразу в избранное!
А Вам Сударь, Огромное спасибо и респект, Удачи ВАМ!!
Огромное Спасибо!
Спасибо Автору за статью! Есть вопрос! Как сделать чтобы при начальной загрузке все корневые пункты меню были свернуты?
Заранее спасибо!
Добрый день, пытаюсь разобраться в вашем скрипте, но что-то не получается.
Как написала Ева
return true; // Prohibit the browser to follow the link address
заменил что был переход по ссылке, но тогда не происходит записи в куки, и получается что подменю не раскрывается :(
А еще бы хотелось при нажатии на плюсик - меню разворачивается, а при нажатии на ссылку - переход по ссылке, т.е. развертывание и свертывание происходили только по нажатию +/- .
Не подскажите что куда дописать?
Отличная статья! Сделал свою менюшку на куки, подскажите как убрать "мигание" панели, т.е. начальное состояние раскрытое, а проверкой в скрипте на куки скрывает ее.. ?
Вот не замечал мигания :)
Но думаю убрать можно так
ul.sample-menu li ul { padding:0;margin:0 0 0 15px; display:none; }
Виктор, мигание получается за счет медленного реагирования скрипта, менюшка успевает показаться на доли секунд (я делал на базе дивов).. решил другим способом, не через jquery.. пришлось прям в тело вставлять скрипт на яве сразу посде нужного <див>..
работает отлично, жаль что jquery работает когда полностью подгрузится..
Есть еще идеи как можно сделать?
и все же, как сделать, чтобы все ссылки меню были рабочими, и при этом меню открывалось? . на что заменить эту строчку, если это конечно помогает
return true; // Prohibit the browser to follow the link address
Как сделать что б при выборе главного пункта, открытый закрывался???
подскажите у всех после обновления FF перестало работать это меню?
Отправить комментарий