Как добавить пункт в контекстное меню браузера

Обновлено: 04.07.2024

Чтобы работа с компьютером была удобной, в операционной системе Windows у каждого файла, папки или любого другого объекта есть контекстное меню. Открывается оно кликом правой кнопкой мышки по этому объекту.

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

Об удалении пунктов читайте здесь. Ниже речь пойдет только об их добавлении в меню.

Чтобы добавить пункт в контекстное меню, необходимо внести изменения в системный реестр Windows. Сделать это можно путем "ручной" правки реестра или при помощи специальных программ (см. последний пункт этой статьи).

Первый способ немного сложный для новичков, но предоставляет более широкие возможности. В статье он рассмотрен максимально подробно. Для лучшего восприятия информация изложена в следующем порядке:

1. Как добавить простой пункт в контекстное меню файла, папки, Рабочего стола, значка "Компьютер" или Корзины;

2. Добавление в меню выпадающего списка из нескольких пунктов;

3. Как добавить пункт или выпадающий список только в меню файлов определенного типа.

1. Добавление в контекстное меню простого пункта

Для внесения изменений в системный реестр необходимо открыть Редактор реестра.

Кратко напомню, как работать в этом редакторе.

Чтобы открыть Редактор реестра нужно на клавиатуре нажать комбинацию клавиш Win+R, в открывшемся окне напечатать или скопировать туда с этой страницы слово regedit , после чего нажать клавишу Enter.

Окно Редактора реестра разделено на две части по вертикали. В левой его части находится проводник. Он предназначен для навигации. Например, чтобы открыть ветку реестра HKEY_CLASSES_ROOT/*/shell, необходимо в проводнике Редактора двойным кликом мышки открыть сначала раздел "HKEY_CLASSES_ROOT", в нем найти и таким же способом открыть раздел "*", а в нем - раздел "shell".

Подробно порядок работы в Редакторе реестра описан в этой статье.

Чтобы добавить пункт в контекстное меню файла, папки, Рабочего стола или любого другого объекта, необходимо открыть Редактор реестра и в соответствующей ветке создать новый раздел с необходимыми параметрами, в которых прописать название пункта, исполняемую им функцию и др.

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

Все зависит от того, в контекстное меню какого объекта необходимо добавить пункт. Если это контекстное меню:

файлов - радел нужно создавать в ветке:

запоминающих устройств (диски, флешки и др.) - в ветке:

значка "Компьютер" - в ветке:

Рабочего стола - в ветке:

значка "Корзина" - в ветке:

Теперь добавим новый пункт в контекстное меню одного из указанных объектов.

Например, в меню файлов добавим пункт, который будет открывать их в браузере Mozilla Firefox.

Порядок действий:

1. В Редакторе реестра открыть соответствующую ветку.

Поскольку в нашем примере пункт должен появиться в контекстном меню файлов, открываем ветку HKEY_CLASSES_ROOT/*/shell;

2. Создать в ней новый раздел.

С этой целью в проводнике Редактора необходимо щелкнуть правой кнопкой мышки по папке "shell", и в открывшемся списке выбрать "Создать" - "Раздел" (см. изображение). Назвать этот раздел можно как угодно, используя латинские буквы и цифры. Я назвал "Open to Firefox".


3. В новом разделе создать строковый параметр с названием MUIVerb (он определяет название пункта контекстного меню).

Для этого в проводнике Редактора реестра нужно щелкнуть правой кнопкой мышки по созданному разделу (который я назвал "Open to Firefox") и в появившемся списке выбрать "Создать" ⇒ "Строковый параметр" (см. изображение).


Новый строковый параметр появится в правой части Редактора реестра. Нужно присвоить ему название MUIVerb, после чего дважды щелкнуть по нему левой кнопкой мышки.

Затем в нижнем поле открывшегося окна указать словосочетание, которое будет отображаться в контекстном меню, и нажать кнопку ОК. Я написал "Открыть в Firefox" (см. изображение).


Кроме параметра MUIVerb, в созданный раздел аналогичным образом можно добавить еще несколько параметров (не обязательно). В частности:

• строковый параметр с названием Position. Он определяет, в каком месте контекстного меню будет находиться пункт. Ему можно присвоить одно из двух значений: Top (вверху) или Bottom (внизу). Если этот параметр не создавать, пункт будет отображаться в середине контекстного меню.

Я создал параметр Position и присвоил ему значение Bottom.

• строковый параметр с названием Icon. Он определяет, какая иконка будет отображаться в контекстном меню слева от пункта.

В значении этого параметра нужно указать путь к файлу иконки формата .ICO. Можно также указать путь к какой-нибудь программе. В таком случае будет использоваться иконка этой программы.

Поскольку создаваемый мною пункт должен открывать файл в браузере Firefox, я указал в нем путь к файлу этого браузера.

• строковый параметр Extended. Если добавить этот параметр в созданный раздел, пункт контекстного меню станет "скрытым". Чтобы он отображался, перед открытием контекстного меню нужно будет нажать и удерживать клавишу Shift.

Этому параметру не нужно присваивать никакого значения (оставить пустым).

В свой пример этот параметр я решил не добавлять.

4. В проводнике редактора реестра снова щелкнуть правой кнопкой мышки по созданному разделу (в моем случае он с названием "Open to Firefox") и в появившемся списке выбрать "Создать" ⇒ "Раздел".

В нашем разделе появится еще один раздел, которому необходимо присвоить название command.

5. Выделить раздел command в проводнике Редактора реестра (щелкнуть по нему мышкой). После этого в правой части Редактора дважды щелкнуть мышкой по параметру с названием "(По умолчанию)".

Затем в нижнем поле открывшегося окна, в поле "Значение", необходимо указать путь к программе, которая должна открываться создаваемым пунктом контекстного меню.

В моем случае пункт должен открывать файл в окне Firefox, поэтому я прописал путь к этому браузеру.

Важно. Через пробел от пути к программе я добавил метку "%1" (см. изображение). Она указывает на то, что пункт должен не просто запустить программу, но и открыть файл в ее окне (без этой метки пункт будет запускать пустое окно браузера).


Новый пункт контекстного меню создан. У меня он получился таким:


2. Добавление в меню
выпадающего списка из нескольких пунктов

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

Предлагаю рассмотреть порядок их создания. В качестве примера добавим в меню файлов пункт "Открыть в браузере", из которого будет выпадать список из 5 браузеров (см. изображение).


Порядок действий:

1. В соответствующем контекстном меню создать простой пункт. При наведении на него будет появляться выпадающий список. Действовать при этом нужно так, как описано выше, за исключением п.5 (раздел command создавать не нужно).

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

• с названием MUIVerb, в значении которого указать название пункта (обязательно);

• с названием Position и значением Bottom или Top (не обязательно);

• с названием Icon и указанием пути к файлу иконки (не обязательно);

Поскольку мне нужно создать выпадающий список в меню файлов, я:

• открыл ветку реестра HKEY_CLASSES_ROOT/*/shell ;

• создал там новый раздел (назвать его можно как угодно, я назвал spisok) ;

• в этом новом разделе создал строковый параметр с названием MUIVerb и значением "Открыть в браузере".

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


2. Кроме перечисленных строковых параметров, в созданном разделе нужно создать еще один строковый параметр и назвать его SubCommands. Этот параметр превращает обычный пункт контекстного меню в выпадающий список.

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

Поскольку выпадающий список из моего примера должен включать 5 браузеров, я придумал 5 названий: raz1, raz2, raz3, raz4, raz5. Записав их через точку с запятой, я получил следующее: raz1;raz2;raz3;raz4;raz5 (см. изображение).


3. В проводнике Редактора реестра перейти в ветку

В этой ветке для каждого пункта выпадающего списка необходимо создать новый раздел. Создаваемым разделам необходимо присвоить названия, которые были указаны в значении строкового параметра SubCommands (см. предыдущий пункт).

Как помните, в своем примере в параметре SubCommands я указал 5 названий: raz1, raz2, raz3, raz4, raz5. Этими названиями я и назвал 5 новосозданных разделов, см. изображение.


4. В каждом из новосозданных разделов необходимо сделать следующее:

• дважды щелкнуть левой кнопкой мышки по строковому параметру с названием "(По умолчанию)" и в открывшемся окне указать название пункта выпадающего меню (обязательно). В каждом из моих 5 разделов я указал здесь название браузера (raz1 - Firefox, raz2 - Opera, raz3 - Chrom, raz4 - Яндекс.Браузер, raz5 - Safari).

• в каждый из созданных разделов добавить строковый параметр с названием Icon (не обязательно) и указать в нем путь к иконке, которая должна отображаться в контекстном меню рядом с пунктом (точно так же, как и в случае с простым пунктом, см. выше);

• в каждом из созданных разделов создать еще один раздел и назвать его command. В разделе command дважды щелкнуть мышкой по параметру с названием "(По умолчанию)" и в открывшемся окне указать путь к программе, которую должен запускать пункт выпадающего списка.

В каждом из моих 5 разделов здесь я указал путь к соответствующему браузеру. И поскольку пункт должен не только запускать браузер, но и открывать файл в его окне, через пробел от пути я добавлял метку "%1", см. изображение.


Вот и все. В результате у меня получился выпадающий список из 5 браузеров (см. изображение выше).

3. Как добавить пункт
только в меню файлов определенного типа

Иногда возникает необходимость добавить пункт в контекстное меню не всех файлов, а только файлов определенного типа, например, файлов формата .txt или .jpg. Давайте разберемся, как это сделать.

Выше уже говорилось, что для добавления пунктов в контекстное меню абсолютно всех файлов нужно создать соответствующие записи в ветке реестра HKEY_CLASSES_ROOT/*/shell .

Чтобы добавить пункт только в меню файлов определенного типа, необходимо добавить те же записи в другую ветку. Что это за ветка - зависит от типа файла и установленного на компьютере программного обеспечения. На каждом конкретном компьютере она будет другой. Но ее всегда можно определить самостоятельно.

Рассмотрим, как это делается, на примере файла формата .jpg

Порядок действий:

1. В Редакторе реестра открыть раздел HKEY_CLASSES_ROOT, найти в нем папку, название которой соответствует требуемому расширению файла, и выделить ее (один раз щелкнуть по ней левой кнопкой мышки).

Учитывая, что в качестве примера был взят файл .jpg, я нашел и выделил папку с названием ".jpg".

2. В правой части Редактора реестра дважды щелкнуть мышкой по строковому параметру с названием "(По умолчанию)" и посмотреть, что указано в его значении. То, что там указано, является названием папки в разделе HKEY_CLASSES_ROOT, в которую необходимо перейти.

На моем компьютере в значении этого параметра указано "jpegfile". Значит, мне необходимо перейти в ветку HKEY_CLASSES_ROOT/jpegfile


3. Перейдя в указанную папку, необходимо найти в ней раздел с названием "shell". Если такого раздела там нет, его необходимо создать. Этот раздел и есть веткой реестра, в которую необходимо добавлять соответствующие записи для создания пункта контекстного меню.

В моем примере, это ветка HKEY_CLASSES_ROOT/jpegfile/shell


4. Программы для добавления пунктов в контекстное меню

Новые пункты в контекстное меню можно добавлять при помощи программ. Вот названия некоторых из них:

Однажды я уже рассказывал на Хабре, как можно добавить собственную команду в контекстное меню браузера Internet Explorer (Удобное дополнение к IE при написании обзоров / Internet Explorer / Хабрахабр). Сейчас я расскажу, как добавить свою команду в контекстное меню Проводника. Поехали.

Информация о контекстном меню Проводника и Рабочего стола хранится в разделе реестра HKEY_CLASSES_ROOT\Directory\Background\Shell. Именно отсюда система узнает, какие команды нужно отобразить в контекстном меню и какие программы нужно запустить, когда пользователь щелкает по выбранной команде меню. Таким образом, вооружившись этими знаниями, мы сможем сами создавать нужные нам команды.

Итак, чтобы добавить новую команду в контекстное меню, достаточно создать в разделе HKCR\Directory\Background\Shell новый подраздел. Предположим, мы хотим, чтобы в меню появилась команда, запускающая стандартный Блокнот. Создаем подраздел notepad и сразу можем проверить и убедиться, что в контекстном меню Рабочего стола появилась одноименная команда. Нам даже не пришлось перезагружать компьютер. Естественно, такая команда не очень нас устраивает, и мы хотим задать собственный текст, например, Блокнотик. Для этого редактируем параметр по умолчанию созданного подраздела и записываем для него новое значение, которое мы хотим видеть, например, прописываем слово Блокнотик. Снова проверяем и убеждаемся, что в контекстном меню появилась наша команда.


  • MUIVerb – значение данного параметра заменяет собой значение параметра по умолчанию, т.е. мы можем в этом параметре задать имя для команды в меню.
  • Extended – при наличии данного параметра без значения говорит системе о том, что команда должна отображаться только при нажатии клавиши Shift. Вы можете посмотреть на подраздел HKEY_CLASSES_ROOT\Directory\Background\shell\cmd, в котором содержится такой параметр. Поэтому, если держать нажатой клавишу Shift, то в контекстном меню появится команда Открыть окно команд.

Теперь перейдем к подразделам. Прежде всего, нужно создать подраздел command. Параметр по умолчанию данного подраздела должен содержать в себе команду, которая будет выполняться при выборе соответствующего элемента контекстного меню. В нашем случае, нужно прописать команду notepad.exe.


Как видите, несколько несложных операций в разделе реестра и мы получаем новую команду для контекстного меню Рабочего стола и Проводника. А зная алгоритм создания новой команды, вы можете изучить и отредактировать параметры от других программ, которые прописали свои разделы в вашей системе.

Включение/выключения эскизов

Рассмотрим практический пример создания собственной команды в меню Проводника. Если вы предпочитаете просматривать файлы в режиме Значки, то заметили, что, например, значки картинок отображаются в виде эскизов. В настройках папки можно изменить данное поведение и отключить показ эскизов. Но включать или отключать эти настройки очень утомительно. Судите сами – сначала надо нажать на клавишу Alt, чтобы появилась строка меню у Проводника, далее выбираем меню Сервис | Параметры папок…. После этого нужно переключиться на вкладку Вид и поставить или убрать флажок у команды Всегда отображать значки, а не эскизы. Упростим задачу при помощи реестра и небольшого VBS-сценария, который циклически меняет значения параметра IconsOnly в разделе HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced. Создадим новый раздел ToggleThumb в разделе HKEY_CURRENT_USER\Software\Classes\Directory\Background\Shell и присвоим параметру по умолчанию строковое значение Включить/Выключить эскизы. Тем самым мы создали новую команду для контекстного меню папки в Проводнике. Обратите внимание, что теперь мы используем раздел HKEY_CURRENT_USER, чтобы действие примера распространялось только на одного пользователя. Теперь создаем подраздел command и прописываем в параметре по умолчанию строку wscript.exe "%WinDir%\togglethumbs.vbs". Далее нужно создать сценарий, который будет переключать режим показа эскизов.

Сохраните созданный сценарий под именем togglethumbs.vbs и скопируйте его в папку Windows.
Теперь вы можете открыть Проводники и проверить работу новой команды. Для удобства я сначала выбрал режим Крупные значки, которые отображаются в виде эскизов.

Отображение файлов в виде эскизов

Далее я выбрал в контекстном меню пункт Включить/Выключить эскизы и получил следующий результат – вместо эскизов я увидел значки программы Adobe Photoshop, ознакомительную версию которой я поставил несколько дней назад на своем компьютере.

Отображение файлов в виде значков

Удаление содержимого папки без удаления самой папки

Практически аналогично добавляется собственная команда и в контекстное меню папки. Недавно я нашел один пример применения контекстного меню папки в Проводнике — Add Empty Folder Contents to Windows 7 Right Click Context Menu. | The Windows Club.

Автор примера рассказывает, как добавить в контекстное меню папки команду для удаления содержимого папки без удаления самой папки. Т.е. вам не придется открывать папку, выделять все файлы и нажимать на клавишу Delete, достаточно выбрать команду Удалить содержимое папки. Я немного модифицировал пример, чтобы он более органично смотрелся на русской версии Windows.

Для этого добавляем в раздел HKEY_CLASSES_ROOT\Directory\shell подраздел DeleteFolderContent и создаем в нем строковый параметр MUIVerb со строкой Удалить содержимое папки. Далее в разделе DeleteFolderContent создаем подраздел command и в его параметре по умолчанию прописываем строчку:

Все готово и можете пользоваться примером.

Заключение

Хочу предупредить, что я рассказал про основные приемы создания команд в контекстном меню Проводника. Реестр — достаточно сложная штука и существуют другие способы работы с контекстном меню.

Если верить Википедии, контекстное меню — меню, появляющееся при взаимодействии пользователя с графическим интерфейсом (при нажатии правой кнопки мыши). Контекстное меню содержит ограниченный набор возможных действий, который обычно связаны с выбранным объектом.

На вашем компьютере клик правой кнопкой мыши на рабочем столе вызовет контекстное меню операционной системы. Отсюда вы, вероятно, можете создать новую папку, получить какую-то информацию и сделать что-нибудь еще. Контекстное меню в браузере позволяет, например, получить информацию о странице, посмотреть ее исходники, сохранить изображение, открыть ссылку в новой вкладке, поработать с буфером обмена и всякое такое. Причем набор доступных действий зависит от того, куда именно вы кликнули, то есть от контекста. Это стандартное поведение, закладываемое разработчиками браузера [И расширений к нему].

Веб-приложения постепенно начинают заменять стандартные контекстные меню своими собственными. Отличными примерами являются все те же Gmail и Dropbox. Вопрос лишь в том, как сделать свое контекстное меню? В браузере при клике правой кнопкой мыши срабатывает событие contextmenu. Нам придется отменить поведение по умолчанию и сделать так, чтобы вместо стандартного меню выводилось наше собственное. Это не так уж сложно, но разбираться будем пошагово, так что выйдет довольно объемно. Для начала создадим базовую структуру приложения, чтоб разрабатываемый пример не был совсем уж оторван от реальности.

Список задач

Пример результата есть на CodePen. Можете заглянуть туда сразу, если лень читать или хотите убедиться, что действительно заинтересованы в дальнейшем чтении. Ну а пока приступим к пошаговой разработке задуманного. Я буду использовать некоторые современные фишки CSS и создам простейший список задач на data-атрибутах. Также воспользуюсь сбросом стилей от Эрика Мейера и сброшу свойство box-sizing для всех элементов в border-box:

Я не буду использовать префиксы в CSS, но в демо на CodePen включен автопрефиксер.

Создание базовой структуры

Откроем наш HTML-документ, накидаем шапку, контентную часть с некоторым списком задач и подвал. Я также подтяну Font Awesome и шрифт Roboto, чтобы сделать оформление немного лучше. Каждая задача должна содержать атрибут data-id, который в реальности брался бы из БД. Также каждая задача будет содержать список действий. Вот важные части разметки:

Если вы используете CodePen, можете в настройках включить автопрефиксер и подключение CSS-сброса. В противном случае придется делать все руками, если еще не автоматизировали этот процесс. Не забывайте, что наша цель — создание контекстного меню, так что обработка действий не будет реализована. А теперь давайте добавим еще немного CSS:

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

Набросаем наше контекстное меню — разметка

  1. Просмотр задачи.
  2. Редактирование задачи.
  3. Удаление задачи.
  1. Мы хотим, чтобы контекстное меню появлялось там, где был выполнен правый клик, то есть ему нужно абсолютное позиционирование. Поэтому не стоит его разметку помещать в контейнер с относительным позиционированием.
  2. Нам потребуются какие-нибудь переменные или атрибуты, чтобы можно было определить, к какой задаче относится выбранное действие.

Приводим наше меню в порядок — CSS

Уже была упомянута необходимость абсолютного позиционирования разрабатываемого меню. Кроме того, установим свойство z-index в 10. Не забывайте, что в вашем приложении может потребоваться другое значение. Это не все возможные стили, в демке наведены прочие красивости, но они уже зависят от ваших потребностей и не являются обязательными. Прежде чем переходить к JS, сделаем меню невидимым по умолчанию и добавим дополнительный класс для его отображения.

Разворачиваем наше контекстное меню — JavaScript

Начнем с того, что посмотрим, как зарегистрировать событие contextmenu. Откроем самовыполняющуюся функцию и отловим событие на всем документе. Также будем логировать событие в консоль, чтобы получить какую-то информацию:

  1. Потребуется цикл по всем элементам списка задач и добавление обработчика события contextmenu к каждому из них.
  2. Для каждого обработчика отменим стандартное поведение.
  3. Будем логировать в консоли событие и элемент, к которому оно относится.

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

Но для начала давайте добавим к меню ID, чтобы его проще было получать посредством JS. Также добавим переменную состояния меню menuState и и переменную с активным классом. Получились три переменных:

Едем дальше. Пересмотрим функцию contextMenuListener и добавим toggleMenuOn, отображающую меню:

На данный момент правой кнопкой мыши уже можно вызвать наше контекстное меню. Но нельзя сказать, что оно работает правильно. Во-первых, оно находится совсем не там, где хотелось бы. Для устранения проблемы понадобится немного математики. Во-вторых, закрыть это меню пока невозможно. С учетом того, как работают обычные контекстные меню, хотелось бы, чтоб наша его реализация закрывалась при клике не меню и при нажатии Escape. Помимо этого при правом клике вне нашего меню оно должно закрыться, а вместо него требуется открытие меню по умолчанию. Давайте попробуем все это решить.

Рефакторинг нашего кода

  1. contextmenu — Проверка состояния и раскрытие контекстного меню.
  2. click — Скрытие меню.
  3. keyup — Обработка нажатий клавиш. В данном руководстве интересна только ESC.
  1. Само проверяемое событие.
  2. Имя класса для сравнения. Если событие произошло внутри элемента, имеющего указанный класс, или родитель этого элемента имеет такой класс, то нужно вернуть этот элемент.

Вернемся и отредактируем contextListener:

Имея вспомогательную функцию, делающую за нас часть грязной работы, и отлавливая событие contextmenu на всем документе, мы можем теперь закрывать меню при клике вне его. Для этого добавим функцию toggleMenuOff и отредактируем contextListener:

Теперь нажмите правой кнопкой по элементу списка. А после — где-нибудь в другом месте документа. Вуаля! Наше меню закрылось и открылось стандартное. Затем сделаем нечто похожее самое для события click, чтобы не от одной правой кнопки оно закрывалось:

Этот кусок кода несколько отличается от предыдущего, потому что Firefox. После того, как правая кнопка мыши отжата, в Firefox срабатывает событие click, так что здесь нам приходится дополнительно убеждаться, что произошел действительно клик левой кнопкой. Теперь меню не моргает при правом клике. Давайте добавим похожий обработчик и на нажатие клавиши ESC:

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

Позиционирование нашего контекстного меню

С учетом текущих HTML и CSS, наше меню отображается в нижней части экрана. Но нам-то хотелось бы, чтоб оно появлялось там, где произошел клик. Давайте исправим сие досадное упущение. Во-первых, добавим еще одну вспомогательную функцию, получающую точные координаты клика. Назовем ее getPosition и попробуем заставить обрабатывать разные причуды браузеров:

Наш первый шаг в позиционировании меню — подготовка трех переменных. Добавим их в соответствующий блок кода:

Создадим функцию positionMenu, принимающую единственный аргумент — событие. Пока что пусть она выводит координаты меню в консоль:

Отредактируем contextListener, чтобы начать процесс позиционирования:

Снова повтыкайте в контекстное меню и загляните в консоль. Убедитесь, что позиция действительно доступна и логируется. Мы можем использовать встроенные стили для задания свойств top и left посредством JS. Вот и новая версия positionMenu:

  1. Что будет, если пользователь кликнет близко к правому краю окна? Контекстное меню выйдет за его пределы.
  2. Что делать, если пользователя меняет размеры окна при открытом контекстном меню? Возникает та же проблема. Dropbox решает эту проблему скрытием переполнения по оси x (x-overflow: hidden).

Как вы помните, по умолчанию наше меню скрыто, так что нельзя просто взять и посчитать его размеры. В нашем случае меню статическое, но при реальном применении его содержимое может меняться в зависимости от контекста, так что рассчитывать ширину и высоту лучше в момент открытия. Получим нужные величины внутри функции positionMenu:

Введем еще две переменных, но на этот раз для размеров окна:

Посчитаем их значения похожим образом:

В конечном счете давайте предположим, что хотим показывать меню не ближе, чем в 4 пикселях от края окна. Можно сравнить значения, как я говорил выше, и скорректировать позицию как-то так:

Сейчас наше меню ведет себя совсем хорошо. Осталось что-то сделать с ресайзом окна. Я уже говорил, как поступает Dropbox, но вместо этого мы будем закрывать контекстное меню. [Такое поведение куда ближе к стандартному] Добавим в функцию init следующую строку:

И напишем саму функцию:

Цепляем события к пунктам контекстного меню

Если ваше приложение сложнее данного примера, и у вас планируется динамическое содержимое контекстного меню, придется подробнее вникнуть в происходящее далее, чтобы самому додумать недостающие детали. В нашем приложении все проще, и есть всего одно меню с постоянным набором действий. Таким образом, можно быстро проверить, какой именно элемент был выбран, и обработать этот выбор. В нашем примере просто сохраним выбранный элемент в переменную и запишем в консоль его data-id и выбранное действие. Для этого отредактируем разметку меню:

Далее давайте закэшируем все нужные объекты:

Появилась переменная taskItemInContext, которой присваивается значение при правом клике по элементу списка. Она нам потребуется для логирования ID элементов. Также появились новые имена классов. Теперь пройдемся по функциональности.

Функция инициализации остается такой же. Первое изменение затрагивает contextListener, ведь мы хотим сохранять в taskItemInContext элемент, на который кликнул пользователь, а функция clickInsideElement как раз его и возвращает:

Мы сбрасываем ее в null, если правый клик произошел не по элементу списка. Ну и возьмемся за clickListener. Как я упоминал ранее, для простоты мы просто будем выводить информацию в консоль. Сейчас при отлавливании события click производится несколько проверок и меню закрывается. Внесем коррективы и начнем обрабатывать клик внутри контекстного меню, выполняя некоторое действие и лишь после этого закрывая меню:

Вы могли заметить, что вызывается функция menuItemListener. Ее мы определим чуть позже. Функции keyupListener, resizeListener и positionMenu оставляем без изменений. Функции toggleMenuOn и toggleMenuOff отредактируем незначительно, изменив имена переменных для лучшей читаемости кода:

Наконец реализуем menuItemListener:

На этом разработка функциональности заканчивается.

Некоторые замечания

  1. На протяжении всей статьи я упоминал правый клик как событие для открытия контекстного меню. Не все являются правшами и не у всех выставлены стандартные настройки мыши. Но вне зависимости от этого, событие contextmenu действует именно в соответствии с настройками мыши, а не привязано жестко к именно правой кнопке.
  2. Еще один важный момент заключается в том, что мы рассмотрели только полноценные настольные веб-приложения с мышью в качестве устройства ввода. Пользователи могут пользоваться клавиатурой или мобильными устройствами, поэтому не забудьте предусмотреть альтернативные способы взаимодействия для сохранения дружественного интерфейса.

Большой вопрос

Совместимость с браузерами

  • Chrome 39
  • Safari 7
  • Firefox 33

Заключение и демо

Если вы тщательно все обдумали и уверены, что такая функциональность нужна вашему приложению, вы можете использовать разработанное меню. Конечно, оно может потребовать каких-либо изменений, но данное руководство подробно описывает процесс разработки, так что реализовывать свои поправки должно быть не так сложно.

Кодовая база этого руководства залита на GitHub и будет поддерживаться и, возможно, обновляться в течение долгого времени. А полное рабочее демо можно потыкать на CodePen.

В рубрике "HTML" Вы найдете бесплатные уроки по работе с этим языком гипертекстовой разметки, который лежит в основе большинства сайтов.

Данная рубрика заменит Вам полноценный «HTML учебник». Здесь Вы сможете найти ответы на большинство вопросов, связанных с HTML и DHTML.

Бесплатные уроки HTML для начинающих

Помимо текстовых уроков, Вы также сможете найти на нашем сайте полезные видео уроки по HTML. Простые и понятные примеры и объяснения помогут Вам в кратчайшие сроки освоить этот базовый язык «сайтостроения».

Лайфхак: наиполезнейшая функция var_export()

При написании или отладки PHP скриптов мы частенько пользуемся функциями var_dump() и print_r() для вывода предварительных данных массив и объектов. В этом посте я бы хотел рассказать вам о функции var_export(), которая может преобразовать массив в формат, пригодный для PHP кода.

Автор/переводчик: Станислав Протасевич

17 бесплатных шаблонов админок

Парочка бесплатных шаблонов панелей администрирования.

Автор/переводчик: Станислав Протасевич

30 сайтов для скачки бесплатных шаблонов почтовых писем

Создание шаблона для письма не такое уж простое дело. Предлагаем вам подборку из 30 сайтов, где можно бесплатно скачать подобные шаблоны на любой вкус.

Автор/переводчик: Станислав Протасевич

Как осуществить задержку при нажатии клавиши с помощью jQuery?

К примеру у вас есть поле поиска, которое обрабатывается при каждом нажатии клавиши клавиатуры. Если кто-то захочет написать слово Windows, AJAX запрос будет отправлен по следующим фрагментам: W, Wi, Win, Wind, Windo, Window, Windows. Проблема?.

Автор/переводчик: Станислав Протасевич

15 новых сайтов для скачивания бесплатных фото

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

Автор/переводчик: Станислав Протасевич

50+ бесплатных Bootstrap 3 шаблонов и элементов UI

Подборка бесплатных UI материалов и Bootstrap 3 шаблонов за уходящий месяц.

Автор/переводчик: Станислав Протасевич

Зум слайдер

Сегодняшний черновик - это простой слайдер с возможностью раскрытия подробной информации о каждом элементе.

Читайте также: