Создаем выпадающее боковое меню на HTML, CSS и JavaScript

Создаем выпадающее боковое меню на HTML, CSS и JavaScript

Создаем выпадающее боковое меню на HTML, CSS и JavaScript

Доброго времени суток! В данной статье мы рассмотрим с Вами как сделать боковое меню с выпадающим подменю, причем
состояние меню будет сохраняться при перезагрузке страницы. Реализация будет на чистом CSS и немного JavaScript.

Итак, код:



<!DOCTYPE html>

<html lang="en">



<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Autoclose menu</title>



    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">



    <style>

        *,

        *::after,

        *::before {

            box-sizing: border-box;

        }



        html,

        body {

            margin: 0;

            padding: 0;

            min-height: 100vh;

        }



        .container {

            display: flex;

            background-color: bisque;

            min-height: 100vh;

        }



        .sidebar-menu {

            padding: 5px 0;

            background-color: rgb(214, 214, 214);

            min-width: 180px;

        }



        .content {

            padding: 5px;

            background-color: burlywood;

            flex-grow: 1;

        }



        ul {

            list-style-type: none;

            padding-left: 0;

        }



        .menu {

            margin: 0;

        }



        .menu-item {}



        .submenu-item {

            padding: 5px 8px;

        }



        .menu-item__header {

            padding: 5px 8px;

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: space-between;

        }



        .menu-item__header:hover,

        .submenu-item:hover {

            background-color: beige;

        }



        .menu-item__header::after {

            font-family: "Bootstrap-icons";

            content: "F282";

            transition: transform 0.3s linear;

        }





        .menu-item__header-open::after {

            font-family: "Bootstrap-icons";

            content: "F282";

            transform: rotate(180deg);

        }



        .submenu {

            padding-left: 0;

            transition: max-height 0.3s ease-in-out;

            max-height: 0;

            overflow: hidden;

        }



        .menu-item__header-open+.submenu {

            max-height: 500px;

        }



        .submenu-item {}

    </style>







</head>



<body>

    <div class="container">

        <aside class="sidebar-menu" id="sidebarmenu">

            <ul class="menu">

                <li class="menu-item">

                    <div class="menu-item__header">Входящие</div>

                    <ul class="submenu">

                        <li class="submenu-item">

                            <a href="">Ссылка номер №1</a>

                        </li>

                        <li class="submenu-item">item 2</li>

                        <li class="submenu-item">item 3</li>

                        <li class="submenu-item">item 4</li>

                        <li class="submenu-item">item 5</li>

                    </ul>

                </li>

                <li class="menu-item">

                    <div class="menu-item__header">Исходящие</div>

                    <ul class="submenu">

                        <li class="submenu-item">item 1</li>

                        <li class="submenu-item">item 2</li>

                        <li class="submenu-item">item 3</li>

                        <li class="submenu-item">item 4</li>

                        <li class="submenu-item">item 5</li>

                    </ul>

                </li>

                <li class="menu-item">

                    <div class="menu-item__header">Другие</div>

                    <ul class="submenu">

                        <li class="submenu-item">item 1</li>

                        <li class="submenu-item">item 2</li>

                        <li class="submenu-item">item 3</li>

                        <li class="submenu-item">item 4</li>

                        <li class="submenu-item">item 5</li>

                    </ul>



                </li>

            </ul>

        </aside>

        <main class="content">

            Some content goes here

        </main>

    </div>



    <script>



    // Функция для обработки событий в боковом меню

    function initSidebarMenu(

        settingsKey = '__sidebarMenu_',   // Ключ для сохранения состояния в локальном хранилище

        menu_id = 'sidebarmenu',          // ID корневого элемента бокового меню

        menu_item_header_class = 'menu-item__header', // Класс заголовков элементов меню

        menu_item_header_open_class = 'menu-item__header-open' // Класс для открытых подменю

    ) 

    {

        // Вспомогательная функция для преобразования строки в хэш

        const toHex = (string) => string.substring(0, 16).split('').map(char => char.charCodeAt(0)).join('');

        // Функция для генерации уникального ключа на основе текста элемента меню

        const keyHash = (key) => settingsKey + toHex(key);



        // Получение элемента бокового меню и заголовков элементов

        const menu = document.getElementById(menu_id);

        const menuItemHeaders = menu.getElementsByClassName(menu_item_header_class);



        // Перебор заголовков и установка состояния открытия/закрытия для каждого

        for (const itemHeader of menuItemHeaders) {

            const state = JSON.parse(localStorage.getItem(keyHash(itemHeader.innerText)));



            if (state) {

                itemHeader.classList.add(menu_item_header_open_class);

            }

        }



        // Добавление обработчика события для бокового меню

        menu.addEventListener('click', function (e) {

            const element = e.target;

            // Проверка, является ли элемент заголовком элемента меню

            if (element.classList.contains(menu_item_header_class)) {

                // Переключение класса для изменения стиля и сохранение состояния в локальном хранилище

                const state = element.classList.toggle(menu_item_header_open_class);

                localStorage.setItem(keyHash(element.innerText), state);

            }

        });

    }



    // Вызов функции инициализации бокового меню при загрузке страницы

    initSidebarMenu();





    </script>

</body>



</html>



Этот код представляет собой веб-страницу с боковым меню, которое поддерживает автоматическое закрытие и открытие подменю при нажатии на заголовок элемента меню. Для сохранения состояния открытия/закрытия подменю при перезагрузке страницы используется локальное хранилище браузера.

Теперь рассмотрим код по частям:

HTML-разметка

  • Есть боковое меню с тремя категориями: «Входящие», «Исходящие», «Другие».
  • В каждой категории есть подменю с пятью элементами.
  • Главное содержимое находится в блоке .
  • CSS-стили

  • Определены стили для бокового меню, заголовков и подменю.
  • Используются иконы Bootstrap для стрелок, обозначающих состояние открытия/закрытия подменю.
  • Применены стили для анимации изменения цвета при наведении и анимации открытия/закрытия подменю.
  • JavaScript-скрипт

  • Функция initSidebarMenu инициализирует боковое меню.
  • Используется локальное хранилище браузера для сохранения состояния открытия/закрытия подменю. Ключи для хранения состояния генерируются на основе текста заголовков элементов меню.
  • При загрузке страницы функция проверяет сохраненное состояние и автоматически открывает подменю для соответствующих элементов.
  • Когда пользователь кликает на заголовок элемента меню, скрипт переключает класс menu-item__header-open, изменяя таким образом стиль элемента и запоминая его состояние в локальном хранилище.

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

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий