Контекстное меню в Firefox



Влад Мержевич

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

Для начала давайте посмотрим, как вообще создаются разные меню. Для этого используется комбинация тегов <menu> и <command> (пример 1).

Пример 1. Контекстное меню

HTML5IECrOpSaFx

<!DOCTYPE html>
<html>
 <head> 
  <meta charset="utf-8"> 
  <title>Контекстное меню</title> 
 </head> 
 <body> 
  <p><img src="images/figure.jpg" alt="" contextmenu="edit"></p> 
  <menu type="context" id="edit"> 
   <command label="Вырезать"> 
   <command label="Копировать"> 
   <command label="Вставить"> 
  </menu> 
 </body> 
</html>

Атрибут contextmenu сообщает, что наше меню является контекстным и одновременно указывает на тег <menu> с заданным идентификатором (в данном случае edit). Пока ни один браузер не понимает приведённый пример, включая Firefox. Для него вместо тега <command> следует вставить нестандартный тег <menuitem> (пример 2).

Пример 2. Меню в Firefox

HTML5IECrOpSaFx

<!DOCTYPE html>
<html> 
 <head> 
  <meta charset="utf-8"> 
  <title>Контекстное меню</title> 
 </head> 
 <body> 
  <p><img src="images/figure.jpg" alt="" contextmenu="edit"></p> 
  <menu type="context" id="edit"> 
   <menuitem label="Вырезать"></menuitem> 
   <menuitem label="Копировать"></menuitem> 
   <menuitem label="Вставить"></menuitem> 
  </menu> 
 </body> 
</html>

Код получился невалидным, зато при щелчке по картинке в Firefox появляется красивое меню (рис. 1).

Контекстное меню

Рис. 1. Контекстное меню

Пока это меню не работает нужным образом, так что переделаем его. Для начала добавим возле пункта меню иконку с помощью атрибута icon, так меню получится симпатичнее. В качестве значения указывается относительный или абсолютный путь к графическому файлу. Затем надо сделать, чтобы при нажатии на пункт меню происходило какое-то действие. Для этого воспользуемся событием onclick и с его помощью будем вызывать нужную функцию. В примере 3 показано создание контекстного меню для текста, если в нём выбрать «Править», то текст можно редактировать. На деле же применяется скрытое текстовое поле, которое становится видимым при вызове функции edit(), сам же текст на время редактирования скрывается. После нажатия на Enter текст из формы вставляется на место текстового абзаца, создавая впечатление, что именно его мы и правили. Форма же после завершения редактирования прячется вновь.

Пример 3. Редактирование текста

HTML5IECrOpSaFx

<!DOCTYPE html> 
<html> 
 <head> 
  <meta charset="utf-8"> 
  <title>Контекстно меню</title> 
  <style> 
   #edit { 
    width: 200px; 
    border: 1px solid #ccc; 
    display: none; 
   } 
  </style> 
  <script> 
   function edit() { 
    document.getElementById('text').style.display = 'none'; 
    document.getElementById('edit').style.display = 'block'; 
    document.getElementById('edit').value = document.getElementById('text').innerHTML; 
    document.getElementById('edit').focus(); 
   } 
   function text() { 
    document.getElementById('text').innerHTML = document.getElementById('edit').value; 
    document.getElementById('edit').style.display = 'none'; 
    document.getElementById('text').style.display = 'block'; 
   } 
  </script> 
 </head> 
 <body> 
  <p id="text" contextmenu="menu">Пример текста</p> 
  <p><form onsubmit="text(); return false"><input id="edit"></form></p> 
   <menu type="context" id="menu"> 
    <menuitem icon="images/edit.png" onclick="edit()">Править</menuitem> 
   </menu> 
 </body> 
</html> 

Вид нового меню показан на рис. 2.

Меню с иконкой

Рис. 2. Меню с иконкой

Как видно из примера, создание контекстного меню ничем не отличается от создания других интерактивных элементов. При нажатии на пункт меню вызывается наша функция с помощью обработчика onclick, а дальше эта функция будет делать то, что мы пожелаем. Firefox 8 стал первым браузером, который начал поддерживать контекстные меню HTML5, но вызывает удивление, почему разработчики Firefox ввели для меню свой собственный нестандартный тег <menuitem>. Здесь возможны несколько вариантов развития событий:

  • тег <menuitem> будет добавлен в спецификацию HTML5;
  • этот тег себя изживёт и не будет поддерживаться в будущих версиях Firefox;

Остаётся только ждать ответа других браузеров, в которых тег <command> наконец-то будет реализован, а также разные меню на его основе.

Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.