Афоризм
Женат два раза; неудачно.
Одна ушла, вторая нет.
Последние статьи

 • Активности Android
Многоэкранные Android приложения
 • Fragment dynamic
Динамическая загрузка фрагментов в Android
 • Fragment lifecycle
Жизненный цикл Fragment'ов в Android
 • Fragment example
Пример Fragment'ов в Android
 • Data Binding
Описание и пример Data Binding
 • Пример MVVM
Пример использования MVVM в Android
 • Компонент TreeTable
Описание компонента TreeTable для Swing
 • Пример TreeTable
Пример использования TreeTable
 • Хранилища Android
Внутренние и внешние хранилища данных
 • Пример SQLite
Пример использования SQLite в Android
 • WebSocket
Описание и пример реализации WebSocket
 • Визуальные компоненты
Улучшен компонент выбора даты из календаря
 • Анимация jQuery
Описание и примеры анимации элементов DOM
 • APK-файл Android
Создание apk-файла для android устройств, .dex файлы
 • платформа JaBricks
Платформа OSGi-приложения JaBricks
Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие
 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698
Перейти к содержанию jQuery

Выпадающее вниз меню, сворачиваемое меню типа аккордеон

Рассмотрим особенности создания навигационных элементов управления содержимым сайта в стиле меню с помощью библиотеки jQuery. Дополнительные возможности библиотеки, необходимые для описания и связанные с выбором элементов, фильтрацией набора, управлением css-стилями, а также всплытие событий рассмотрено на других страницах, по ссылкам на которые Вы можете перейти. На этой странице рассмотрим горизонтальное меню с выпадающими вниз элементами и вертикальное меню типа «аккордеон» со сворачиваемыми элементами. И начнем с выпадающего вниз меню.

Выпадающее вниз меню

Для создания простого выпадающего меню определим css-стили и структуру в html-коде, а управление включим в js-скрипты (javascript). То есть, в html-коде будет представлена статика, динамика – в скриптах. Чтобы меню реагировало на мышь при наведении и покидании курсора будем использовать событие hover библиотеки jQuery. Кроме этого, при обработке события наведения курсора создадим небольшую задержку, по окончании которой меню будет разворачиваться. Таким образом, событие hover будет инициироваться при задержке пользователем курсора на пункте меню, предупреждая ложные «проскакивания» курсора над элементом. Ниже представлена демонстрация нашего простенького примера.

Листинг CSS-стилей

В примере используется минимальный набор опций CSS-стилей : убираем списочное изображение • опцией list-style, определяем форму курсора (cursor) при наведении на элемент меню.

Скрыть css-стили


<style>
   ul.parent > li {
      position         : relative;
      float            : left;
      list-style       : none;
      margin           : 0;
      margin-right     : 2px;
      border           : 1px solid #888;
      padding          : 5px 15px;
      background-color : #ccc;
      cursor           : pointer;
   }
   ul.child {
      position         : absolute;
      left             : 0;
      padding-top      : 5px;
      padding-left     : 15px;
      list-style       : none;
      display          : none;
   }
</style>
 

Листинг html-кода

Структуру горизонтального двухуровнего меню создадим из списочных элементов ul и их дочерних li. У каждого ссылочного элемента определим класс "link", который используем в скриптах для обработки нажатия click.

Скрыть листинг html-кода


<ul class="parent">
    <li>Услуги
        <ul class="child">
            <li class="link">service 1</li>
            <li class="link">service 2</li>
            <li class="link">service 3</li>
        </ul>
    </li>
    <li>Продукты
        <ul class="child">
            <li class="link">product 1</li>
            <li class="link">product 2</li>
            <li class="link">product 3</li>
        </ul>
    </li>
    <li>Помощь
        <ul class="child">
            <li class="link">help 1</li>
            <li class="link">help 2</li>
            <li class="link">help 3</li>
        </ul>
    </li>
</ul>
 

Листинг js-кода

Представленные ниже скрипты завернуты в функцию document-ready, которая выполняется сразу же после загрузки страницы и формирования структуры DOM. Данная функция включает два обработчика. Первый обработчик реагирует на события hover, т.е. на наведение курсора и его покидание элемента меню верхнего уровня. Второй обработчик реагирует на нажатие click. Селектором $(".parent li") выбирается набор элементов верхнего уровня li, к которым подключается обработчик hover. Селектором с фильтром $(".parent li").filter(".link") выбираются дочерние элементы li, т.е. ссылочные подпункты меню.

Обработчик события hover
в качестве параметров получает две функции. Первая функция вызывается при наведении курсора, вторая функция – при покидании.

При наведении курсора на элемент меню верхнего уровня li у него определяется класс 'waiting'. После этого вызовом метода setTimeout согласно значению второго параметра устанавливается временна́я задержка 600мс. По истечении данной задержки выполняется функция, определенная в качестве первого параметра метода setTimeout. Обратите внимание, что перед вызовом метода setTimeout запоминается элемент меню в переменной li, которая используется для проверки наличия класса 'waiting' и сворачивания дочерних/ссылочных элементов. Если курсор успеет покинуть элемент за время задержки, то вторая функция hover удалит у него класс 'waiting', в противном случае у элемента будет раскрыта дочерняя область с ссылочными элементами.

Обработчик события click
открывает окно с сообщением alert. В функции используется метод stopPropagation, блокирующий всплытие событий. Его можно не использовать, поскольку у родительского элемента нет обработчиков нажатий click, но знать и помнить это необходимо.

Скрыть листинг js-кода

<script>
$(document).ready(function() {
    // обработчик события hover
    $(".parent li").hover(function() {
        $(this).addClass('waiting');
        let li = $(this);
        setTimeout(function() {
            if (li.hasClass('waiting'))
                li.find(".child").slideDown(300);
        }, 600);
    }, function() {
       $(this).removeClass('waiting');
       $(this).find(".child").slideUp(300);
    });	

    // обработчик события click
    $(".parent li").filter(".link").on("click",function(e){
        e.stopPropagation();
        alert($(this).text());
    });
})
</script>
 

Демонстрация примера

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

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

  • Услуги
  • Продукты
  • Помощь

Меню с автоматическим сворачиванием

Для вертикальной навигации характерна система меню, у которой подпункты меню группируются по определенным категориям и пользователь без труда может найти нужную ему информацию. Такая система меню имеет иерархическую, как правило, двухуровневую структуру (возможно, конечно и многоуровневая). На верхнем уровне располагаются групповые пункты, которые позволяют сворачивать и разворачивать дочерние подпункты меню. Таким образом, в небольшой области страницы можно разместить большой объем информации.

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

Рассмотрим пример простого меню «аккордеон», которое позволяет разворачивать только одну область меню и сворачивать все элементы. Листинг html-кода примера представлен ниже. В секции заголовка <head> определены css-стили пунктов меню. В теле страницы (<body>) размещается списочный элемент <ul> с несколькими дочерними элементами <li> — это групповые пункты меню верхнего уровня, включающие дочерние списочные элементы ul с подпунктами меню li.

Бизнес-логика поведения списочных элементов меню «аккордеон» определяется css-стилями и javascript-кодом. Ниже представлена демонстрация примера.

Скрыть листинг html-кода

<head>
   <style>
      .level-1 : {
         display        : inline-block;
         width          : 140px;
      }
      ul.menu-rollup {
         list-style-type: none;
         cursor         : pointer;
         width          : 140px;
         padding-left   : 10px;
         margin-left    : 10px;
         border         : 1px solid #888;
      }
      ul.menu-rollup li {
         width     : 140px;
         background:url(images/jquery/dn.png) no-repeat right top;
      }
      ul.menu-rollup li li {
         background-image:none;
      }
   </style>
</head>
<body>
<ul class="menu-rollup">
   <li><b class="level-1">Услуги</b>
       <ul class="level-2">
           <li class="level-2">услуга 1</li>
           <li class="level-2">услуга 2</li>
       </ul>
   </li>
   <li><b class="level-1">Продукты</b>
       <ul class="level-2">
           <li class="level-2">продукт 1</li>
           <li class="level-2">продукт 2</li>
       </ul>
   </li>
   <li><b class="level-1">Помощь</b>
       <ul class="level-2">
           <li class="level-2">помощь 1</li>
           <li class="level-2">помощь 2</li>
       </ul>
   </li>
</ul>
</body>
 

Листинг js-скриптов

Код js (javascript) включает анонимную фунцию, в которой выполняется несколько действий. Сначала селектором выбираются все элементы второго уровня ul и методом hide они скрываются. Дальше представлены две функции, которые подключаются к DOM-элементам. Первая функция обрабатывает событие click пункта меню верхнего уровня, а вторая функция обрабатывает нажатие дочерних подпунктов меню. В заключении кода выполняется обработка первого/верхнего пункта меню : раскрытие и изменение изображения. У каждого верхнего пункта меню справа представлено изображение, которое может менять вид в зависимости от представления или скрытия дочерних элементов.

Обработчик нажатия верхнего пункта меню
выбирает все дочерние элементы методом nextAll и вызывает для них метод slideToggle (показать/скрыть). Поскольку в структуре меню определен только один дочерний элемент <ul>, то вместо nextAll можно было бы использовать метод next. Метод slideToggle после завершения анимации вызывает callback-функцию, в которой проверяется представление дочерних элементов. Выражением sub[0] мы выбираем первый DOM-элемент из набора и проверяем его высоту; можно также использовать метод height. В зависимости от высоты элемента для его родителя устанавливается соответствующее изображение. Почему проверяется высота? Дело в том, что методом slideToggle изменяется высота DOM-элемента : при скрытии высота обнуляется. На втором шаге для всех недочерних элементов вызывается метод slideUp (свернуть), и в callback-функции определяются стрелки вниз (dn.png).

Обработчик нажатия подпункта меню
Чтобы подключить обработчики к подпунктам меню 2-го уровня выбираются все элементы li с классом 'level-2', после чего в цикле к каждому элементу подключается анонимная функция, открывающая окно с сообщением alert. Здесь следует обратить внимание на вызов метода stopPropagation, который предупреждает всплытие события click, т.е. блокирует вызов метода click родительского элемента.

Скрыть листинг js-скриптов


<script>
$(function(){
   // выбираем подпункты меню 2-го уровня
   let ul = $(".menu-rollup ul.level-2");
   // скрываем все подпункты меню 2-го уровня
   ul.hide();

   // функция обработки нажатия верхнего пункта меню
   $(".menu-rollup").on("click", ".level-1", function() {
      let sub = $(this).nextAll("ul");
      sub.slideToggle("fast", function() {
         // функция изменения изображения
         if (sub[0].clientHeight > 0)
            // определение изображения "стрелки вверх"
            $(this).parent()
                   .css('background', 
                        'url(up.png) no-repeat right top');
         else
            // определение изображения "стрелки вниз"
            $(this).parent()
                   .css('background', 
                        'url(dn.png) no-repeat right top');
      });
      ul.not(sub).slideUp("fast", function() {
         // функция установления изображений "стрелки вниз"
         ul.not(sub).each(function() {
            $(this).parent()
                   .css('background', 
                        'url(dn.png) no-repeat right top');
         });
      });
   });

   // нажатие на один из подпунктов меню
   $(".menu-rollup li").find('.level-2').each(function() {
      $(this).on("click", function() {
         // блокирование всплытия события
         event.stopPropagation();
         alert($(this).text());
      });
   });

   // раскрываем первый пункт меню
   ul.first().show();
   // устанавливаем изображение
   $(".menu-rollup > li")
      .first()
      .css('background','url(up.png) no-repeat right top');
});
</script>
 

Примечание : вместо использования двух методов закрытия ul.hide и открытия ul.first().show() можно использовать селектор с фильтром, который свернет все области за исключением первой :


ul.filter(':not(:first)').hide();
 

Демонстрация примера

Ниже представлена демонстрация примера вертикального меню «аккордеон» с автоматическим сворачиванием. При открытии страницы сразу же разворачивается первый пункт меню "Услуги". При выборе любого другого пункта меню первого уровня ("Продукты", "Помощь") список его подпунктов разворачивается, а раскрытые ранее подпункты сворачиваются. Повторное нажатие на пункт меню первого уровня скрывает его дочерние элементы. Стрелки отображают направление разворачивания (вниз) или сворачивания (вверх). При выборе одного из подпунктов меню (ссылки) открывается окно alert с подтверждением действия.

  Рейтинг@Mail.ru