Раскрывающееся меню на Jquery

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

В этой статье я опишу как можно с помощью jquery из обычного многоуровневого меню сделать раскрывающееся без правки исходного html-кода. Нам просто понадобится выполнить некий javascript-код после загрузки страницы.

Для этого допустим, что на сайте есть такое меню:

Меню: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;
    });
  });
});

Здесь мы делаем следующие вещи:

  1. когда дерево DOM документа готово, пробегаемся в цикле по всем подменю (ul#my-menu ul);
  2. в каждой итерации назначаем класс 'collapsible' ссылке, которая отвечает за данное подменю;
  3. этой же ссылке назначаем обработчик события 'click', который в зависимости от состояния подменю будет раскрывать либо скрывать его.
  4. onlick возвращает '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 можно проверить если потыкать на ссылки и перезагрузить страницу — подменю сохранят свое состояние.

Посмотреть исходники можно в прикрепленном архиве. Удачи!

Файлы: 

Комментарии

Только глюк есть один, небольшой, но портит картину - раскрываем "продукцию" и затем "алко..." к примеру. на "алко..." стоит минус. затем закрываем "продукцию" и снова открываем ее - теперь "алко..." по-прежнему открыто, но на нем стоит +
а в целом очень даже ничего! )))

Добавить комментарий

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешённые HTML-теги: <a> <em> <i> <strong> <b> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <br>
  • Строки и параграфы переносятся автоматически.

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.
CAPTCHA
CAPTCHA на основе изображений
Введите код с картинки