Почти как настоящее
В прошлый раз мы научились менять стандартное контекстное меню браузера на своё. Но наше меню получилось слишком простым и некрасивым, а ещё им сложно было управлять из скрипта. Сегодня мы исправим оба недостатка и сделаем красиво:
Готовим страницу
В предыдущем проекте мы на страницу добавили только пустой блок, а всё остальное делали через скрипт. Это не очень удобно — если нужно добавить или убрать какие-то элементы, надо идти в скрипт и править всё там. На этот раз сделаем иначе — сверстаем контекстное меню как часть страницы, а потом в скрипте скроем его.
Чтобы меню получилось красивым, сразу подключим новый шрифт и нормализатор — он уберёт всё лишнее оформление в браузерах и позволит нам настраивать внешний вид по своему усмотрению.
Наполним наше меню и используем для этого список, как и прошлый раз. Но если тогда мы делали единое меню, то сейчас добавим разделы — они будут отделяться друг от друга и группировать по смыслу разные пункты меню. Для этого добавим к каждому такому списку класс "menu-list". Внутрь этого списка мы сложим все элементы нашего меню, причём у каждого элемента списка будет класс "menu-item" — так мы сможем настраивать внешний вид всех элементов.
А теперь сложная часть: каждый пункт меню сделаем кнопкой — так мы сможем легко обрабатывать нажатия и группировать визуальные элементы в меню. Сначала в кнопку мы положим иконку c помощью тега <i> — он устанавливает курсивное начертание текста, но текста в нём не будет, только иконка. После этого мы пишем название кнопки и закрываем тег кнопки.
Чтобы было понятнее, разберём первый элемент максимально подробно:
На странице появились две кнопки со стандартным оформлением — это нормально, потому что мы ещё не настраивали стили. Но на кнопках нет иконок, которые мы прописывали в теге <i>, — а всё потому, что браузер ничего не знает про эти иконки и откуда их брать. Чтобы это исправить, используем js-библиотеку иконок Feather, которая работает так:
- Мы на странице указываем название иконки, которую хотим получить, с помощью свойства data-feather, например data-feather="edit-2"
- Потом подключаем библиотеку на странице:
<script src='https://unpkg.com/feather-icons@4.29.0/dist/feather.min.js'></script> - А затем подключаем свой скрипт script.js и в нём пишем команду:
feather.replace(); - Эта команда находит на странице все ссылки на иконки и меняет их на SVG-картинки.
Сделаем всё это и посмотрим на результат:
Точно так же, по разделам, сделаем всё остальное меню. Единственное, что нам понадобится дополнительно — это новый список с классом «menu-sub-list» для вложенного меню. Читайте комментарии в коде, чтобы было проще понять, что происходит на странице:
Настраиваем стили
Мы не будем задавать жёсткие размеры для меню — они будут зависеть от текста внутри каждого пункта и подстраиваться под него. Для этого скажем всем элементам, чтобы они смотрели на контент и свои размеры считали относительно содержимого.
Также сразу добавим блок c CSS-переменными — так мы сможем настраивать все цвета на странице в одном месте — и подключим новый шрифт:
Настраиваем меню и разделы
Сделаем из нашего простого списка кнопок что-то похожее на меню: добавим подложку со скруглёнными краями, тени и разделители между разделами.
С разделителями поступим хитро: мы нарисуем верхнюю границу только в том разделе, перед которым тоже есть свой раздел. Так мы сможем добавлять сколько угодно разделов, а разделители нарисуются автоматически.
Скрываем вложенное меню
Сейчас у нашего контекстного меню есть большой минус — вложенное меню видно сразу, хотя оно должно появляться только при наведении мышки на соответствующий пункт. Исправим это, добавив два новых блока в стили:
Настраиваем внешний вид кнопок
Сейчас кнопки в меню выглядят как кнопки, а так быть не должно. Добавим в стили настройки кнопок: уберём границы, сделаем тот же фон, что у подложки, и настроим отступы:
Вроде хорошо, но иконки всё ещё слишком близко к тексту. А ещё они того же цвета, что и текст, а так быть не должно — сделаем их серыми:
Добавляем выделение элемента при наведении мышки
Чтобы явно выделить нужный элемент меню при выборе, добавим ему свой фон и сделаем иконку более заметной — раскрасим её в цвет текста. Так будет сразу понятно, с каким пунктом мы работаем. Заодно добавим красный цвет на пункт «Удалить» при наведении:
Раскрашиваем иконки во вложенном меню
Последнее, что нам осталось сделать в стилях, — раскрасить иконки во вложенном меню. Используем для этого цвета из глобальных переменных, которые мы описали в самом начале:
Пишем скрипт
Сейчас меню выглядит красиво, но его сразу видно на странице и оно не работает как контекстное меню. Настоящее контекстное меню пока никуда не исчезло:
Чтобы это исправить, добавим в наш скрипт два обработчика: первый уберёт родное контекстное меню браузера и покажет наше вместо него, а второй — скроет наше меню, если мы кликнем в любом другом месте страницы.
Обратите внимание — мы передаём координаты top и left в стили, чтобы контекстное меню появилось именно там, где мы щёлкнули мышкой, а не просто в левом верхнем углу.
Посмотреть работу меню на странице проекта.