论坛首页 Web前端技术论坛

Jquery 右键菜单(ContextMenu)插件

浏览 7821 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-03-03   最后修改:2011-03-03
目前做的项目需要在页面里面用右键菜单,在网上找到两种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;background-color:green">trigger1</div>

		<div id="trigger2" style="width:100px;height:100px;background-color:green">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);
   发表时间:2011-03-08  
下载来看了,功能菜单都不错。只是做的 demo 难看了点,点击时的提示信息不太好清楚。不过,demo 做得好看与否与你的右键菜单无关。支持一下!
0 请登录后投票
   发表时间:2011-03-09  
lqixv 写道
下载来看了,功能菜单都不错。只是做的 demo 难看了点,点击时的提示信息不太好清楚。不过,demo 做得好看与否与你的右键菜单无关。支持一下!

:)demo没太认真写,其实就是我当时自己测试用的。
我主要是合并了几个现有的contextMenu的功能,按照自己使用的时候的需求修改了一下。
0 请登录后投票
   发表时间:2011-03-10  
最近正在找右键菜单的东西,正好先研究下
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics