Jquery 右键菜单(ContextMenu)插件使用记录
目前做的项目需要在页面里面用右键菜单,在网上找到两种jquery的右键菜单插件,但是都有各种问题。所以就自己动手把两种插件结合了下。
修改后的右键菜单插架可以根据绑定的触发页面元素不同,复用同一个菜单使之根据触发页面元素有不同的行为。
支持多个个触发页面元素复用同一个菜单时,分开禁用或恢复禁用菜单或某些菜单项目。
一些说明:
1.菜单的样式由css文件contextMenu.css决定,可以根据需要自行修改,请根据实际情况设定z-index的值,保证菜单在最高的一层
2.请将菜单直接放于body下,至少不要让菜单的样式需要受除body外的样式来决定,因为在绑定的时候会把菜单移动到body下面。
3.这个插件是我根据http://www.trendskitchens.co.nz/jquery/contextmenu/和
http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/在后者的基础上修改的。
4.目前粗略测试在ie8,chrome,firefox下面工作正常.
5.例子和js代码打包在附件的文件中
下面是一个例子:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link href="css/ContextMenu.css" rel="stylesheet" type="text/css" />
- <script src="js/lib/jquery-1.4.2.min.js" type="text/javascript"></script>
- <script src="js/lib/jquery.contextMenu.js" type="text/javascript"></script>
- <script type="text/javascript">
- $(document).ready(function() {
- $("#trigger1").contextMenu({
- menuId: 'contextMenu',
- onContextMenuItemSelected:function(menuItemId, $triggerElement){
- alert('trigger1'+menuItemId+' '+$triggerElement.attr('id'))
- },
- onContextMenuShow:function($triggerElement){
- alert('trigger1'+$triggerElement.attr('id'))
- },
- showShadow:false
- });
- $("#trigger1").disableContextMenuItems(['edit'])
- //$("#trigger1").enableContextMenuItems(['edit']) //解除某个菜单项的屏蔽
- //$("#trigger1").disableContextMenu(); //屏蔽菜单
- $("#trigger2").contextMenu({
- menuId: 'contextMenu',
- onContextMenuItemSelected:function(menuItemId, $triggerElement){
- alert('trigger2'+menuItemId+' '+$triggerElement.attr('id'))
- },
- onContextMenuShow:function($triggerElement){
- alert('trigger2'+$triggerElement.attr('id'))
- }
- });
- $("#trigger2").disableContextMenuItems(['delete']) //屏蔽某个菜单项
- //$("#trigger2").enableContextMenuItems(['delete']) //解除某个菜单项的屏蔽
- })
- </script>
- </head>
- <body>
- <ul id="contextMenu" class="contextMenu">
- <li id="delete" class="delete">
- <a>删除</a>
- </li>
- <li id="edit" class="edit">
- <a>修改</a>
- </li>
- </ul>
- <div id="trigger1" style="width:100px;height:100px; font-weight: bold;">>trigger1</div>
- <div id="trigger2" style="width:100px;height:100px; font-weight: bold;">>trigger2</div>
- </body>
- </html>
插件的代码如下:
- // 原作者信息:
- // jQuery Context Menu Plugin
- //
- // Version 1.01
- //
- // Cory S.N. LaViska
- // A Beautiful Site (http://abeautifulsite.net/)
- //
- // More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
- //
- // Terms of Use
- //
- // This plugin is dual-licensed under the GNU General Public License
- // and the MIT License and is copyright A Beautiful Site, LLC.
- //
- // mod信息:
- // modified by shadowlin 2011-03-02
- if(jQuery)(function(){
- //全局变量
- var $shadow;
- var defaults={
- menuId:null,
- onContextMenuItemSelected:function(menuItemId, $triggerElement) {
- },
- onContextMenuShow:function($triggerElement){
- },
- showShadow:true,
- fadeInSpeed:150,
- fadeOutSpeed:75
- }
- $.extend($.fn, {
- contextMenu: function(o) {
- // Defaults
- if( o.menuId == undefined ) return false;//如果没有menuId则退出
- if( o.fadeInSpeed == undefined ) o.fadeInSpeed = defaults.fadeInSpeed;
- if( o.fadeOutSpeed == undefined ) o.fadeOutSpeed = defaults.fadeOutSpeed;
- if( o.showShadow == undefined ) o.showShadow = defaults.showShadow;
- // 0 needs to be -1 for expected results (no fade)
- if( o.fadeInSpeed == 0 ) o.fadeInSpeed = -1;
- if( o.fadeOutSpeed == 0 ) o.fadeOutSpeed = -1;
- // Loop each context menu
- var $menu = $('#' + o.menuId);
- //把menu移动到body下面,避免计算位置的时候出现问题
- if($menu.data('isMovedToBody')!=true){//只移动一次
- $menu.appendTo('body').data('isMovedToBody',true);
- }
- if(!$shadow){
- $shadow = $('<div></div>').css( {
- backgroundColor : '#000',
- position : 'absolute',
- opacity : 0.4
- }).appendTo('body').hide();
- }
- $(this).each(function(){
- var $triggerElement = $(this);
- $triggerElement.data('contextMenu',{
- $menu:$menu,
- isEnabled:true,
- disabledMenuItemIdList:[]
- })
- // Add contextMenu class
- $menu.addClass('contextMenu');
- $triggerElement.unbind('contextmenu').bind('contextmenu',function(e){
- var $currentTriggerElement=$(this);
- var contextMenu=$currentTriggerElement.data('contextMenu');
- //检查菜单是否被屏蔽
- if($currentTriggerElement.data('contextMenu').isEnabled===false) return false;
- //如果有定义onContextMenuShow,在显示前调用
- if(typeof o.onContextMenuShow=='function'){
- o.onContextMenuShow($currentTriggerElement);
- }
- //显示右键菜单
- showMenu(e);
- //绑定菜单项
- $menu.find('li').removeClass('disabled');
- var disabledMenuItemIdList=contextMenu.disabledMenuItemIdList;
- var queryStr='';
- if(disabledMenuItemIdList.length>0){
- var strDisabledMenuItemIdList='';
- for(var index in disabledMenuItemIdList){
- var disabledMenuItemId=disabledMenuItemIdList[index];
- if(index==0){
- strDisabledMenuItemIdList+='#'+disabledMenuItemId;
- }else{
- strDisabledMenuItemIdList+=',#'+disabledMenuItemId;
- }
- }
- queryStr='li:not('+strDisabledMenuItemIdList+')';
- $menu.find(strDisabledMenuItemIdList).addClass('disabled');
- }else{
- queryStr='li';
- }
- $menu.find('li').find('a').unbind('click');
- $menu.find(queryStr).find('a').bind('click',$currentTriggerElement,function(event){
- // Callback
- var callback=o.onContextMenuItemSelected;
- if(typeof callback=='function' ){
- callback( $(this).parent().attr('id'),event.data);
- }
- hideMenu();
- return false;
- });
- $(document).unbind('mousedown').bind('mousedown',function(event) {
- if($(event.target).parents('#'+o.menuId).html()==null){
- hideMenu();
- }
- });
- //阻止默认右键菜单
- return false;
- })
- // Disable text selection
- if( $.browser.mozilla ) {
- $menu.each( function() { $(this).css({ 'MozUserSelect' : 'none' }); });
- } else if( $.browser.msie ) {
- $menu.each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
- } else {
- $menu.each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
- }
- });
- function showMenu(event){
- //显示菜单
- $menu.css({
- 'left' : event.pageX,
- 'top' : event.pageY
- }).fadeIn(o.fadeInSpeed);
- //显示阴影
- if(o.showShadow){
- $shadow.css('zIndex',$menu.css('zIndex')-1);
- $shadow.css( {
- width : $menu.outerWidth(),
- height : $menu.outerHeight(),
- left : event.pageX + 2,
- top : event.pageY + 2
- }).fadeIn(o.fadeInSpeed);
- }
- }
- function hideMenu(){
- $menu.fadeOut(o.fadeOutSpeed);
- if(o.showShadow){
- $shadow.fadeOut(o.fadeOutSpeed);
- }
- }
- return $(this);
- },
- /**
- * 参数为id数组,如无参数则disable全部
- */
- disableContextMenuItems: function(o) {
- $(this).each(function(){
- var contextMenu=$(this).data('contextMenu');
- var $menu=contextMenu.$menu;
- if(o==undefined) {
- var list=[];
- $menu.find('li').each(function(){
- var menuItemId=$(this).attr('id');
- list.push(menuItemId);
- })
- contextMenu.disabledMenuItemIdList=list
- }else{
- contextMenu.disabledMenuItemIdList=o
- }
- })
- return( $(this) );
- },
- // Enable context menu items on the fly
- enableContextMenuItems: function(o) {
- $(this).each(function(){
- var contextMenu=$(this).data('contextMenu');
- var $menu=contextMenu.$menu;
- if(o==undefined) {
- contextMenu.disabledMenuItemIdList=[]
- }else{
- contextMenu.disabledMenuItemIdList=$.grep(contextMenu.disabledMenuItemIdList,function(value,index){
- if($.inArray(value,o)!=-1){
- return false;
- }else{
- return true
- }
- })
- }
- })
- return( $(this) );
- },
- // Disable context menu(s)
- disableContextMenu: function() {
- $(this).each( function() {
- var contextMenu=$(this).data('contextMenu');
- contextMenu.isEnabled=false;
- });
- return( $(this) );
- },
- // Enable context menu(s)
- enableContextMenu: function() {
- $(this).each( function() {
- var contextMenu=$(this).data('contextMenu');
- contextMenu.isEnabled=true;
- });
- return( $(this) );
- },
- // Destroy context menu(s)
- destroyContextMenu: function() {
- $(this).each( function() {
- $(this).removeData('contextMenu');
- });
- return( $(this) );
- }
- });
- })(jQuery);