Доброго времени суток.
Сегодня я хочу поделиться опытом написания своего контекстного меню с помощью всеми нами любимой библиотеки jQuery.
Итак, немного предыстории
Что подтолкнуло меня к тому, что я заинтересовался вопросом написания своего контекстного меню и решил написать эту статью? А то, что я являюсь большим фанатом продуктов Google и мне всегда очень нравился подход этой компании к интерфейсам пользователя.
Ежедневно пользуясь его продуктами, такими как Google Drive, меня всегда поражало, до чего же удобно выполнять различные операции с помощью знакомого с детства контекстного меню, просто кликая на объекте правой кнопкой мыши и выбирая необходимое действие. Этот факт и заставил меня заинтересоваться, а насколько сложно самостоятельно реализовать вызов своего контекстного меню в браузере, по клику на любой объект, а так же запретить вызов стандартного меню браузера?
Я решил попробовать и вот что у меня получилось.
К делу
Естественно первое с чего нужно начать, это подключить библиотеку jQuery:
<script type="text/javascript" src="js/jquery.js"></script>
Далее нужно запретить вызов стандартного контекстного меню браузера. Для этого нужно добавить слушатель на стандартное событие документа oncontextmenu и просто предотвратить дальнейшее выполнение стандартных действий вернув false:
document.oncontextmenu = function() {return false;};
Далее необходимо сделать то, с чего обычно начинается большинство действий в jQuery, а именно повесить слушатель на событие готовности DOM:
$(document).ready(function(){
// Все начинается тут
});
Заранее напишем немного css:
/* Класс контекстного меню: */
.context-menu {
position: absolute; /* Задаем абсолютное позиционирование для нашего меню */
display: none; /* Изначально не показываем его */
background-color: #fff; /* Цвет фона меню */
border: 1px solid #333; /* Граница */
/* Немного красивостей. Добавляем тень для нашего меню, что бы отобразить его слегка выше остальных элементов страницы: */
-moz-box-shadow: -5px 2px 10px rgba(0,0,0,0.5); /* Для Firefox */
-webkit-box-shadow: -5px 2px 10px rgba(0,0,0,0.5); /* Для Safari и Chrome */
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; }
Теперь все готово и мы можем начинать творить чудеса jQuery:
$(document).ready(function() {
// Вешаем слушатель события нажатие кнопок мыши для всего документа:
$(document).mousedown(function(event) {
// Убираем css класс selected-html-element у абсолютно всех элементов на странице с помощью селектора "*":
$('*').removeClass('selected-html-element');
// Удаляем предыдущие вызванное контекстное меню:
$('.context-menu').remove();
// Проверяем нажата ли именно правая кнопка мыши:
if (event.which === 3) {
// Получаем элемент на котором был совершен клик:
var target = $(event.target);
// Добавляем класс selected-html-element что бы наглядно показать на чем именно мы кликнули (исключительно для тестирования):
target.addClass('selected-html-element');
// Создаем меню:
$('<div/>', {
class: 'context-menu' // Присваиваем блоку наш css класс контекстного меню:
})
.css({
left: event.pageX+'px', // Задаем позицию меню на X
top: event.pageY+'px' // Задаем позицию меню по Y
})
.appendTo('body') // Присоединяем наше меню к body документа:
.append( // Добавляем пункты меню:
$('<ul/>').append('<li><a href="#">Remove element</a></li>')
.append('<li><a href="#">Add element</a></li>')
.append('<li><a href="#">Element style</a></li>')
.append('<li><a href="#">Element props</a></li>')
.append('<li><a href="#">Open Inspector</a></li>')
)
.show('fast'); // Показываем меню с небольшим стандартным эффектом jQuery. Как раз очень хорошо подходит для меню
}
});
});
Далее все что нужно сделать, это добавить несколько любых HTML элементов на страницу для тестирования.
Вот что получится:
Так же хотелось бы заострить внимание еще на нескольких вещах:
- Вам вовсе не обязательно вешать события нажатия кнопки мыши именно на весь документ. При желании вы можете повесить его на кокой либо блок, с помощью класса или идентификатора, тем самым обеспечив поддержку своего меню только в определенной области
- Очень важным фактом здесь является то, что мы имеем возможность получить тот объект, на котором был произведен клик. Таким образом в дальнейшем мы можем производить над ним любые действия (для чего и призвано контекстное меню). Например менять его свойства, удалить его или добавить в него дочерний элемент.
Спасибо всем за внимание. Надеюсь кому то пригодиться этот рецепт.
Хорошего дня!
Автор: ilmor
Благодарю! Очень помогли! +++
Сам то ты на чёрном фоне что либо видишь? Увидеть то можно, если изрядно напрячся! А нужно ли это? Меня тема заинтересовала и мне пришлось копировать фрагменты в редактор.
Скрипт хороший, но есть один неприятный момент:
при вызове меню с элементов модального окна, оно отображается под модалью и соответственно недоступно.
Это можно как то поправить?
В CSS можно задать для контекстного меню z-index: 999 и всё будет работать!