Статьи

Реализация кросс-браузерного контекстного меню в виде плагина jQuery

Часто вам нужно иметь собственное контекстное меню где-нибудь на вашей странице. Скорее всего, вы уже используете jQuery на своем веб-сайте, поскольку jQuery используется на половине всех веб-сайтов . Из этого туториала вы узнаете, как реализовать собственный плагин jQuery для создания кросс-браузерных контекстных меню. Конечный результат будет состоять из одного файла JavaScript и одного файла CSS, который можно легко добавить на ваши страницы.

В целях продвижения передового опыта плагин будет использовать рекомендации, предложенные плагином jQuery, в качестве отправной точки. Если вам нужны дополнительные советы, вы также можете взглянуть на 10 советов по разработке лучших плагинов jQuery .

Основы

В этом уроке плагин будет называться «контекстным меню Audero». Это имя произвольное, поэтому не стесняйтесь называть его как хотите. Начальная точка файла JavaScript взята со страницы рекомендаций jQuery. Подводя итог, мы будем использовать IIFE, чтобы плагин не сталкивался с другими библиотеками, использующими знак доллара, такими как Prototype . Мы также будем использовать пространство имен, чтобы у плагина была очень низкая вероятность перезаписи другим кодом, находящимся на той же странице. Выбранное пространство имен — auderoContextMenu . В строке 2 фрагмента ниже мы добавляем пространство имен как свойство объекта $.fn . Вместо того, чтобы добавлять каждый метод к объекту $.fn , мы поместим их в литерал объекта в соответствии с рекомендациями. Методы плагина могут быть вызваны путем передачи имени метода в виде строки.

 (function($) { $.fn.auderoContextMenu = function(method) { if (methods[method]) return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); else if (typeof method === 'object' || typeof method === 'string' || ! method) return methods.init.apply(this, arguments); else $.error('Method ' + method + ' does not exist on jQuery.auderoContextMenu'); }; })(jQuery); 

Как вы можете видеть, условие else if немного отличается от рекомендаций. Мы добавили тест, чтобы проверить, является ли параметр method строкой. Это позволяет пользователю использовать плагин, просто передавая единственный параметр, который должен быть id пользовательского контекстного меню. Это означает, что создаваемое нами контекстное меню, которое вы увидите просто как список, будет частью DOM . Плагин работает, заменяя поведение по умолчанию для события щелчка правой кнопкой мыши, но, как вы увидите позже, переопределение левого щелчка также легко.

Начиная

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

  1. метод init()
  2. метод show()
  3. метод hide()
  4. настройки по умолчанию

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

 (function($) { // default values used for the menu var defaultValues = {'idMenu': null, 'posX': null, 'posY': null}; // settings for all the elements and menu specified by the user var elementsSettings = {}; var methods = { /* here we'll write the init, show and hide methods */ } $.fn.auderoContextMenu = function(method) { // Here is the code shown previously }; })(jQuery); 

Теперь пришло время увидеть детали методов init() , show() и hide() упомянутых выше.

Метод init()

Этот метод, как и следовало ожидать, инициализирует настройки контекстного меню и переопределяет поведение по умолчанию для события щелчка правой кнопкой мыши. Он также определяет выбранный элемент, выбранное контекстное меню и позицию его отображения. Метод init() принимает один параметр, который может быть объектом или строкой. Если объект указан, он должен содержать id меню и координаты для его позиционирования. Если пользователь предоставляет объект, он будет объединен с настройками по умолчанию с помощью метода jQuery extend () . Если указана строка, она используется в качестве id меню для отображения.

 this.on('contextmenu auderoContextMenu', function(event) { event.preventDefault(); event.stopPropagation(); var params = $.extend({}, elementsSettings[id]); if (elementsSettings[id].posX == null || elementsSettings[id].posY == null) { params.posX = event.pageX; params.posY = event.pageY; } methods.show(params, event, id); }); 

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

Метод show()

Метод show() отображает меню в соответствующей позиции. Этот метод начинается с сокрытия меню, которое будет показано. Это сделано, потому что это могло уже быть видно из-за предыдущего вызова метода. Меню можно скрыть с помощью метода jQuery hide () , но поскольку наш плагин определяет метод hide() , мы будем использовать наш метод, как показано ниже.

 methods.hide(idMenu); 

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

 if (typeof params !== 'object' || params.posX == undefined || params.posY == undefined) { if (event == undefined) { params = {'idMenu': params, 'posX': 0, 'posY': 0} } else { params = {'idMenu': params, 'posX': event.pageX, 'posY': event.pageY} } } 

Код, который на самом деле отображает меню, довольно прост. Мы используем jQuery, чтобы получить меню через его id , затем устанавливаем позицию (в пикселях), начиная с верхнего левого угла. Наконец, метод jQuery show() используется для отображения меню. Благодаря цепочке jQuery эти шаги выполняются всего одним оператором, как показано ниже. Наше удивительное меню теперь волшебным образом появляется.

 $('#' + idMenu) .css('top', params.posY + 'px') .css('left', params.posX + 'px') .show(); 

Метод hide()

Метод hide() будет использоваться для скрытия меню. Поскольку наш плагин позволяет отображать несколько контекстных меню одновременно, будет удобно иметь возможность скрыть все меню одновременно. Наш метод hide() принимает один необязательный параметр, который представляет скрытые меню. Если указан, параметр может быть строкой или массивом строк. Если параметр имеет значение null или undefined , то все меню в elementsSettings будут рекурсивно скрыты.

 hide: function(id) { if (id === undefined || id === null) { for(var Key in elementsSettings) methods.hide(elementsSettings[Key].idMenu); } else if ($.isArray(id)) { for(i = 0; i < id.length; i++) methods.hide(id[i]); } else $('#' + id).hide(); } 

Добавление некоторого стиля!

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

 ul.audero-context-menu { position: absolute; display: none; background-color: menu; list-style-type: none !important; margin: 0px !important; padding: 0px !important; } ul.audero-context-menu * { color: menutext; } ul.audero-context-menu > li { border: 1px solid black; margin: 0px !important; padding: 2px 5px !important; } ul.audero-context-menu > li:hover { background-color: activecaption; } ul.audero-context-menu > li a { display: block; } 

Использование плагина

Наш плагин очень прост в использовании. Фактически, его основное использование состоит только из одной строки кода. Например, допустим, у нас есть следующий фрагмент HTML.

 <ul id="context-menu" class="audero-context-menu"> <li><a href="http://www.sitepoint.com">SitePoint</a></li> <li><a href="http://ug.audero.it">Audero user group</a></li> </ul> <div id="area">Right click here to show the custom menu.</div> 

Чтобы позволить плагину показывать пользовательское контекстное меню, context-menu , при щелчке правой кнопкой мыши по области вы должны написать следующий код.

 $(document).ready (function() { $('#area').auderoContextMenu('context-menu'); }); 

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

 $('#area').click (function(event) { $(this).auderoContextMenu('show', 'context-menu', event); }); 

Выводы

В этом руководстве показано, как создать плагин jQuery, который создает пользовательские контекстные меню. Чтобы увидеть, как это работает, посмотрите онлайн-демонстрацию или загрузите исходный код . Если вам нужно больше примеров или подробное объяснение методов, пожалуйста, обратитесь к официальной документации . Контекстное меню Audero является полностью бесплатным и выпускается под лицензией CC BY 3.0 .