Делаем новое контекстное меню на странице

Делаем новое контекстное меню на странице

Меняем стандартное меню на своё

Если мы нажмём на правую кнопку мыши на любой странице, то увидим контекстное меню браузера:

Делаем новое контекстное меню на странице

Но в некоторых онлайн-сервисах, например в Фигме, появляется не стандартное контекстное меню, а другое, связанное с работой сервиса. 

Сегодня расскажем, как сделать такое меню у себя на странице и что для этого потребуется.

Делаем новое контекстное меню на странице
Контекстное меню в Фигме

Готовим страницу

Так как единственное, что нам нужно, — это контекстное меню, то на странице разместим один заголовок, и всё. Можно даже его не добавлять, но тогда будет непонятно, загрузилась страница или нет. 

<!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;};

Теперь по нажатии на правую кнопку мыши мы не увидим ничего, а значит, новое меню нам нужно нарисовать самим.

Рисуем меню

Логика нового меню будет такая:

  1. Ждём, пока страница полностью загрузится.
  2. Как только нажата правая кнопка мыши — создаём новый блок на странице.
  3. В этом блоке простым списком добавляем наши пункты меню.
  4. Делаем этот блок видимым.
  5. Если нажата любая другая кнопка мыши — убираем этот блок.

Хитрость здесь будет в том, что мы будем в конце убирать контекстное меню не моментально, а с задержкой в 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; }
Делаем новое контекстное меню на странице

Что дальше

Теперь, когда вы знаете, как сделать такое меню, можно сделать следующий шаг, например:

  • добавить иконки, чтобы пользоваться меню стало удобнее;
  • повесить на каждый пункт вызов какой-нибудь полезной функции;
  • показывать разные меню в зависимости от элемента, на котором кликнули мышкой;
  • красиво оформить меню (как в «Фигме», например).

В будущих статьях сделаем это. Подписывайтесь, чтобы быть в курсе. 

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Алина Грызлова

Веб-разработка — это новый чёрный
На базе веб-технологий делают всё — от сложного софта до высокобюджетных игр. Изучите технологии и начните карьеру в ИТ. Старт бесплатно. Попробуйте, вдруг вам понравится.
Изучить
Веб-разработка — это новый чёрный
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Как школьный учитель стал фронтенд-разработчиком
Как школьный учитель стал фронтенд-разработчиком

О старте карьеры фронтенд-разработчика

easy
Как в России появился каршеринг
Как в России появился каршеринг

Конспект подкаста «Запуск завтра»

easy
Vim: текстовый редактор для мастеров
Vim: текстовый редактор для мастеров

Очень сложная штука, но мы попытаемся объяснить просто.

easy
Как работает автоматизация в компьютере
Как работает автоматизация в компьютере

Пусть потеет машина

easy
Angular, C# и WebRTC: как устроен российский софт для видеозвонков
Angular, C# и WebRTC: как устроен российский софт для видеозвонков

Говорим с ребятами из «Контура»

easy
Что такое «задача коммивояжёра»
Что такое «задача коммивояжёра»

Благодаря ей у нас есть навигаторы и системы принятия решений.

easy
Симметричное шифрование
Симметричное шифрование

Простое, но очень стойкое.

medium
5 гаджетов c Алиэкспресса для хранения и защиты данных
5 гаджетов c Алиэкспресса для хранения и защиты данных

Чтобы можно было везде взять с собой

easy
Объясни мне: как опубликовать свой сайт в интернете

Покупаем домен, оформляем хостинг, настраиваем привязку и заливаем файлы. Купаемся в лучах славы.

medium
Что такое перегрузка операторов
Что такое перегрузка операторов

Для тех, кто пытался, но не понял.

hard
medium