. . .

Выпадающее меню

17 Июнь 2019

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

В этой статье я рассмотрю как создается такой выпадающий список, речь пойдет о какой-то простой базовой разметке на html, простом css оформлении и функциях на js, которые заставят все это работать так, как нужно работать.

Сначала создадим разметку:

<div id="drop-nav">
    <p id="main-item">Мужская одежда</p>
    <ul id="main-item-list">
        <li class="list-item">Рубашки</li>
        <li class="list-item">Свитшоты</li>
        <li class="list-item">Джинсы</li>
    </ul>
</div>

Добавим базовое оформление:

#drop-nav {
    width: 300px;
}
#drop-nav #main-item {
    font-size: 18px;
    font-weight: 700;
    margin: 0;
    padding: 15px;
}
#drop-nav #main-item-list {
    list-style-type: none;
    margin: 0;
    padding: 0;
    display: none;
}
#drop-nav #main-item-list li {
    display: block;
    padding: 15px;
    border-bottom: 1px solid #aaa;
}

Я не очень люблю стилизовать по id элемента, всегда думал что он предназначен скорее для перехода по элементам на странице или для поиска этого элемента js, а для стилизации лучше использовать классы, но для простоты понимания оставим так как есть. На данном этапе у нас есть некий пункт меню и список, который скрыт:

Мужская одежда

  • Рубашки
  • Свитшоты
  • Джинсы

Теперь можно приступить js-части. Мы напишем три функции: первая будет отслеживать событие наведения курсора на базовый раздел и по этому наведению будет устанавливать у списка с подразделами свойство display: block. Вторая функция будет отвечать за скрытие списка с подразделами. И, наконец, третья функция будет также отслеживать наведения курсора, и если курсор не будет находится на базовом разделе, выпадающем списке или элементе выпадающего списка, то он будет скрываться при помощи второй функции.

//первая функция, с аргументом event, event - объект события
document.getElementById('main-item').onmouseover = function (event) {
    //создаем переменную, которая принимает цель события onmouseover
    var target = event.target;
    //если цель события - наш базовый раздел, делаем видимым список
    if (target.id == 'main-item') {
        document.getElementById('main-item-list').style.display = 'block';
    }
}
//просто функция, которая делает список невидимым
function closeMenu () {
    document.getElementById('main-item-list').style.display = 'none';
}
//третья функция
document.onmouseover = function (event) {
    var target = event.target;
    /* если цель события не базовый элемент, не список, не элемент
    списка, то выполняется вторая функция - скрытие списка
    */
    if (target.id != 'main-item' && target.id != 'main-item-list' && target.className != 'list-item') {
        closeMenu();
    }
}

Выпадающий список готов, вот его рабочий образец:

Мужская одежда

  • Рубашки
  • Свитшоты
  • Джинсы

Хотелось бы отдельно обратить внимание на третью функцию, которая отслеживает наведение на базовый элемент, список или элементы списка. В реальном проекте в элементе списка будет элемент-ссылка (<a href=``">Рубашки</a>). Проверку наведения на этот элемент так же нужно будет указать среди всех остальных.

Посмотреть на github