Контекстное меню HTML без фреймворка
Без каких-либо фреймворков добавьте контекстное меню в JavaScript и CSS к элементам приложения или веб-страницы.
Этот скрипт совместим с IE9, Firefox, Chrome, Safari.
Меню по умолчанию может быть заменено щелчком правой кнопки мыши на меню, выбранном для этого элемента интерфейса. Если вы просто хотите показать окно или список, когда мышь переходит на элемент, вы будете использовать подсказку.
Известно, что по атрибуту onClick обнаруживается щелчок любой кнопки, но для ответа на правую кнопку используется атрибут onSpecttMenu.
Первый шаг - удалить контекстное меню по умолчанию. Для этого достаточно вернуться ложным.
<div oncontextmenu="return false"></div>
Поскольку в ответ на событие мы собираемся вызвать функцию, функция должна будет вернуть false и вернуть результат функции следующим образом:
<div oncontextmenu="return mafonction()"></div>
Для построения контекстного меню функция генерирует слой, который динамически заполняется списком элементов меню. Например, добавляются команды «Переименовать» и «Править». Таблица стилей статически включается в страницу, содержащую сценарий.
Вот демонстрация сценария, за которой следует полный исходный код.
HTML-код прост :
<div oncontextmenu="return monmenu(this)"> Démonstration : Cliquez le bouton droit </div>
Код JavaScript сначала захватывает текущую позицию мыши, чтобы разместить созданное контекстное меню над соответствующим элементом.
Определенная функция работает на всех современных браузерах. Поскольку скрипт предназначен для приложения, можно застопорить инструменты навигации прошлого.
var xMousePosition = 0; var yMousePosition = 0; document.onmousemove = function(e) { xMousePosition = e.clientX + window.pageXOffset; yMousePosition = e.clientY + window.pageYOffset; };
Атрибуты pageXOfset и pageYOfset позволяют учитывать ход страницы (что на самом деле бесполезно, если интерфейс не работает в окне браузера).
Можно обойтись без этой функции, поместив контекстное меню как потомок соответствующего элемента, а не его контейнера, и дать ему фиксированное положение рядом с этим элементом.
Затем меню создается и размещается в соответствии с положением мыши.
Полный код JavaScript из контекстного меню
var xMousePosition = 0; var yMousePosition = 0; document.onmousemove = function(e) { xMousePosition = e.clientX + window.pageXOffset; yMousePosition = e.clientY + window.pageYOffset; }; function rename(element) { alert("Renommer"); } function edit(element) { alert("Editer"); } function monmenu(element) { var x = document.getElementById('ctxmenu1'); if(x) x.parentNode.removeChild(x); var d = document.createElement('div'); d.setAttribute('class', 'ctxmenu'); d.setAttribute('id', 'ctxmenu1'); element.parentNode.appendChild(d); d.style.left = xMousePosition + "px"; d.style.top = yMousePosition + "px"; d.onmouseover = function(e) { this.style.cursor = 'pointer'; } d.onclick = function(e) { element.parentNode.removeChild(d); } document.body.onclick = function(e) { element.parentNode.removeChild(d); } var p = document.createElement('p'); d.appendChild(p); p.onclick=function() { rename(element) }; p.setAttribute('class', 'ctxline'); p.innerHTML = "Renommer"; var p2 = document.createElement('p'); d.appendChild(p2); p2.onclick=function() { edit(element) }; p2.setAttribute('class', 'ctxline'); p2.innerHTML = "Editer"; return false; }
Элементы remame () и edit () используются только для демонстрации и будут заменены собственными функциями.
Этот код отражает два варианта конструкции:
- Меню создается динамически путем вставки новых тегов в DOM.
- Функции добавления строк нет, для каждой команды создается конкретный код. Этого достаточно, если в приложении мало контекстных меню, но придется развивать, если у нас много. На самом деле достаточно просто добавить строку путем копирования/вставки и изменения данных.
Созданное таким образом меню эквивалентно следующему статическому коду, где видно, что было бы сложнее связать события с тегами:
<body onclick="document.getElementById('ctxmenu1').parentNode.removeChild(d);"> <div class="ctxmenu" id="ctxmenu1" onmouseover="this.style.cursor = 'pointer'" onclick="this.parentNode.parentNode.removeChild(this)"> <p class="ctxline" onclick="rename(element)">Renommer</p> <p class="ctxline" onclick="edit(element)">Editer</p> </div>
Переменная элемента представляет объект, с которым связано контекстное меню. В нашем примере имя файла в списке.
Полный код CSS
.ctxmenu { position:absolute; min-width: 128px; height:auto; padding: 8px; margin:0; margin-left:32px; margin-top:-16px; border: 1px solid #999; background: #F8F8F8; box-shadow: 2px 2px 2px #AAA; z-index:11; overflow: visible; } .ctxline { display:block; margin:0px; padding:2px 2px 2px 8px; border:1px solid #F8F8F8; border-radius:3px; font-size:13px; font-family:Arial, Helvetica, sans-serif; overflow:visible; } .ctxline:hover { border:1px solid #BBB; background-color: #F0F0F0; background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); background-image: linear-gradient(top, #ffffff, #e6e6e6); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); }
Некоторые свойства важны:
- Абсолютная позиция для меню (.ctxmenu). Это позволяет указать значения left и top, которые игнорируются в других режимах.
- overflow: видимый, чтобы: меню всегда было видимым, даже если оно выходит за пределы контейнера.
- экран: блок для строк (.ctxline). Это позволяет настроить тег <p> .
Остальное - вопрос внешнего вида.
Была предпринята попытка сделать вид, довольно похожий на внешний вид стандартной среды Windows. Поскольку внешний вид элементов Windows зависит от темы, выбранной пользователем, внешний вид контекстных меню в системе может не быть таким же. Но лучше на этом плане сделать сложно...
Ограничение
Когда я использую это контекстное меню в производстве, иногда браузер инкрементально присваивает свойства left и top, добавляя заданные значения к значениям контейнера. На самом деле это связано с <! doctype html> HTML 5 и не происходит с предыдущими доктипами.
Чтобы обойти эту проблему, можно добавить меню в качестве потомка объекта, с которым оно связано, и расположить меню статически, с отрицательным значением сверху. Но мы также можем изменить доктор.
На самом деле наилучшее решение - сделать положение контейнера статическим (это значение по умолчанию):
#content
{
position:absolute;
left: 218px;
top: 92px;
}
Заменить:
#content
{
position:static;
margin-left: 218px;
margin-top: 92px;
}
Это то, что было сделано для текущей страницы. Таким образом, свойства top и left правильно назначаются для меню.