Если мы нажмём на правую кнопку мыши на любой странице, то увидим контекстное меню браузера:
Но в некоторых онлайн-сервисах, например в Фигме, появляется не стандартное контекстное меню, а другое, связанное с работой сервиса.
Сегодня расскажем, как сделать такое меню у себя на странице и что для этого потребуется.
Готовим страницу
Так как единственное, что нам нужно, — это контекстное меню, то на странице разместим один заголовок, и всё. Можно даже его не добавлять, но тогда будет непонятно, загрузилась страница или нет.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Контекстное меню</title>
</head>
<body>
<h1>Новое контекстное меню</h1>
</body>
</html>
Подключаем библиотеку и отключаем стандартное контекстное меню
Чтобы всё сработало, подключим jQuery — через него мы будем работать с новым меню:
<script src=”https://code.jquery.com/jquery-3.6.0.js” type=”text/javascript”></script>
Добавляем тег <script> на страницу, и первое, что нам нужно, — отключить стандартное контекстное меню:
// запрещаем вызов стандартного меню
document.oncontextmenu = function() {return false;};
Теперь по нажатии на правую кнопку мыши мы не увидим ничего, а значит, новое меню нам нужно нарисовать самим.
Рисуем меню
Логика нового меню будет такая:
- Ждём, пока страница полностью загрузится.
- Как только нажата правая кнопка мыши — создаём новый блок на странице.
- В этом блоке простым списком добавляем наши пункты меню.
- Делаем этот блок видимым.
- Если нажата любая другая кнопка мыши — убираем этот блок.
Хитрость здесь будет в том, что мы будем в конце убирать контекстное меню не моментально, а с задержкой в 10 миллисекунд. Если делать без задержки, то меню просто не будет работать — в момент нажатия на любой пункт скрипт сразу скроет меню и обработать нажатие уже не получится. Чтобы скрипт успевал среагировать на выбор любого пункта, сделаем паузу в 10 миллисекунд — глазу незаметно, а скрипт успеет сработать.
<!-- основной скрипт -->
<script type="text/javascript">
// запрещаем вызов стандартного меню
document.oncontextmenu = function() {return false;};
// когда страница полностью загрузилась — можно показывать новое меню
$(document).ready(function() {
// отслеживаем нажатие мыши на странице
$(document).mousedown(function(event) {
// если нажата правая кнопка мыши
if (event.which === 3) {
// создаём новый блок, в котором будет наше меню
$('<div/>', {
// назначаем ему свой класс, описанный в стилях, чтобы блок появился на странице
class: 'context-menu'
})
.css({
// получаем координаты клика и делаем их координатами меню
left: event.pageX+'px',
top: event.pageY+'px'
})
// добавляем блок на страницу
.appendTo('body')
// и добавляем пункты в новое контекстное меню
.append(
$('<ul/>').append('<li><a href="https://thecode.media">Привет!</a></li>')
.append('<li><a href="https://thecode.media">Это журнал «Код»!</a></li>')
.append('<li><a href="https://thecode.media">А это — новое контекстное меню</a></li>')
)
// показываем новое меню
.show('fast');
}
if (event.which != 3) {
// убираем наше контекстное меню со страницы
setTimeout(() => { $('.context-menu').remove(); }, 10); }
});
});
</script>
Теперь при нажатии правой кнопкой мыши на странице появляется такой список. Он работает, но совсем не похож внешне на контекстное меню. Всё дело в том, что мы не сделали стили, которые отвечают за его внешний вид. Давайте это исправим.
Оформляем стили
Чтобы контекстное меню было похоже на привычное меню, сделаем вокруг него рамку, поменяем шрифт и установим абсолютное позиционирование — оно нужно для того, чтобы меню появлялось точно в месте клика. Чтобы было ещё красивее, добавим тень под меню, чтобы оно появлялось как бы поверх страницы:
/* внешний вид меню */
.context-menu {
/* настройки шрифта */
font-family: sans-serif;
/* устанавливаем абсолютное позиционирование */
position: absolute;
/* не показываем меню с самого начала */
display: none;
/* цвет фона и настройки рамки вокруг меню */
background-color: #fff;
border: 1px solid #333;
padding: 5px;
/* Добавим тени */
-moz-box-shadow: 5px 2px 10px rgba(0,0,0,0.5);
-webkit-box-shadow: 5px 2px 10px rgba(0,0,0,0.5);
box-shadow: 5px 2px 10px rgba(0,0,0,0.5);
}
Осталось оформить элементы меню — белый фон, отступы и изменение фона элемента при наведении курсора:
/* общий стиль для списка */
.context-menu ul { list-style: none; margin: 0; padding: 0; }
/* стиль отдельных элементов */
.context-menu ul li { margin: 0; padding: 0; background-color: #fff; display: block; }
/* стиль ссылок в меню */
.context-menu ul li a { color: #333; text-decoration: none; font-size: 12px; display: block; padding: 5px; }
/* меняем фон в пункте меню при наведении мыши */
.context-menu ul li a:hover { background-color: #eee; }
Что дальше
Теперь, когда вы знаете, как сделать такое меню, можно сделать следующий шаг, например:
- добавить иконки, чтобы пользоваться меню стало удобнее;
- повесить на каждый пункт вызов какой-нибудь полезной функции;
- показывать разные меню в зависимости от элемента, на котором кликнули мышкой;
- красиво оформить меню (как в «Фигме», например).
В будущих статьях сделаем это. Подписывайтесь, чтобы быть в курсе.