发一个增加右键菜单的JQuery标签页插件

前面的话


首先声明,这个JQuery插件不是我写的,我只是将代码改了一部分而已,在此感谢原作者。

其次替作者推广一下他的作品,这是一个类ExtJS的Tab标签页插件,虽然不是什么高深的东西,但个人使用中感觉还是不错的。

作者的原帖请看这里:

http://www.iteye.com/topic/421360

看到回复中有人质疑作者为什么要重复制造轮子,而且这轮子还不如别人造的圆;而我觉得虽然ExtJS或者其它JQuery插件已经实现了这种东西,而且有很多,但作者自己再写一个为什么不可以呢?作者自己从中学到了东西满足自己成就感的同时,又为大家提供了又一个选择,这不是挺好的事儿吗?

插件怎么用这里不说,有需要的请到作者的原帖中找寻,这里只说一下自己添加右键菜单的修改点。

修改后的插件代码请到这里下载:http://download.csdn.net/detail/zhangyihui1986/5187048


修改原因


原来的TabPanel(即JQuery Tab页面插件)的标签没有右键菜单,其实是浏览器默认的,感觉怪怪地,因为像ExtJS及其它成套的JQuery UI组件中的Tab页面组件都有右键菜单,菜单项包括“关闭/关闭所有/关闭其它/刷新”等功能,于是就想能不能自己扩展一下,也将右键菜单加上以提高用户体验。

花了多半天功夫(水平太次)研究了一下源码,觉得不是很难,于是就将菜单加上了,如下所示:

菜单的样式模仿LigerUI的样子,这里也感谢一下LigerUI的作者。LigerUI其实也算是挺好的一个JQuery UI组件,组件齐全,但Bug挺多,而且文档不全,作者很久没有更新,用过两次之后不敢再用了。


修改点


菜单的UI完全通过JS代码生成,并动态添加去除CSS样式来实现的。


1、CSS修改


首先在原来的TabPanel.css中添加如下样式(样式主要来自LigerUI)

.l-menu {
	border: 1px solid #979797;
	background: #F5F5F5;
	position: absolute;
	overflow: hidden;
	padding-bottom: 2px;
	z-index: 1001;
}
.l-menu-yline {
	background: url('../image/TabPanel/menu-line-y.gif') repeat-y;
	width: 2px;
	height: 2000px;
	position: absolute;
	left: 28px;
	top: 1px;
	z-index: 101;
}
.l-menu-over {
	position: absolute;
	top: -24px;
	left: 2px;
	z-index: 102;
	height: 22px;
	overflow: hidden;
	background: url('../image/TabPanel/menu-item-over-m.gif') repeat-x;
	width: 97%;
}
.l-menu-over-l {
	background: url('../image/TabPanel/menu-item-over-l.gif') no-repeat;
	width: 28px;
	height: 22px;
	position: absolute;
	top: 0;
	left: 0;
}
.l-menu-over-r {
	background: url('../image/TabPanel/menu-item-over-r.gif') no-repeat;
	width: 3px;
	height: 22px;
	position: absolute;
	top: 0;
	right: 0;
}
.l-menu-inner {
	position: relative;
	width: 100%;
	z-index: 103;
}
.l-menu-item {
	position: relative;
	height: 23px;
	line-height: 23px;
	width: 100%;
	cursor: pointer;
}
.l-menu-item-text {
	color: #000000;
	left: 33px;
	position: absolute;
	top: 0;
}
.l-menu-item-icon {
	left: 3px;
	top: 0;
	position: absolute;
	width: 25px;
	height: 22px;
	overflow: hidden;
}
.l-icon-reload {
	background: url('../image/TabPanel/refresh.png') no-repeat center;
}
.l-icon-close {
	background: url('../image/TabPanel/close.png') no-repeat center;
}
.l-menu-item-disable {
	cursor: default;
}
.l-menu-item-disable .l-menu-item-text {
	color: #A1A1A1;
}

2、修改TabPanel.js

然后就是修改插件源代码。


2.1、初始化调用


首先在TabPanel初始化方法中调用自己写的CreateMenu方法将弹出菜单创建出来;然后给document对象绑定鼠标单击事件,在事件的响应函数中,将弹出菜单隐藏起来,也就是说如果之前菜单是显示的,当我们在当前页面上点击鼠标左键时弹出菜单隐藏。

this.menu = this.createMenu();
$(document).bind('click', function() {
	if (!tabEntity.menu)
		return;
	tabEntity.menu.hide();
});


2.2、创建菜单


然后定义弹出菜单的生成方法createMenu。

首先创建菜单项承载层DIV,然后循环添加四个菜单项并绑定相应的响应函数,在菜单项配置中可以看到,当鼠标单击某菜单项时会调用_menuItemClick方法并将菜单项配置作为参数传入。最后将弹出菜单追加到body中,由于承载层被定义CSS代码:display:none,所以一开始菜单并不显示。

createMenu : function() {
	var tabEntity = this,
	    menu = $('<div class="l-menu" style="display:none"><div class="l-menu-yline"></div><div class="l-menu-over"><div class="l-menu-over-l"></div><div class="l-menu-over-r"></div></div><div class="l-menu-inner"></div></div>');
	menu.items = $("> .l-menu-inner:first", menu);
	var allitems = [ {
		text : '关闭',
		id : 'close',
		icon: 'close',
		click : function() {
			tabEntity._menuItemClick.apply(tabEntity, arguments);
		}
	}, {
		text : '关闭其它',
		id : 'closeother',
		click : function() {
			tabEntity._menuItemClick.apply(tabEntity, arguments);
		}
	}, {
		text : '关闭所有',
		id : 'closeall',
		click : function() {
			tabEntity._menuItemClick.apply(tabEntity, arguments);
		}
	}, {
		text : '刷新',
		id : 'reload',
		icon: 'reload',
		click : function() {
			tabEntity._menuItemClick.apply(tabEntity, arguments);
		}
	} ];
	for (var i = 0; i < allitems.length; i++) {
		var item = allitems[i],
		    ditem = $('<div class="l-menu-item"><div class="l-menu-item-text"></div></div>');
		ditem.attr("menuitemid", item.id);
		$(">.l-menu-item-text:first", ditem).html(item.text);
		item.icon && ditem.prepend('<div class="l-menu-item-icon l-icon-' + item.icon + '"></div>');
		ditem.click(function(i) {
			return function() {
				if ($(this).hasClass("l-menu-item-disable"))
					return;
				item.click(i);
			}
		}(item));
		var menuover = $("> .l-menu-over:first", menu);
		ditem.hover(function() {
			if ($(this).hasClass("l-menu-item-disable"))
				return;
			var itemtop = $(this).offset().top;
			var top = itemtop - menu.offset().top;
			menuover.css({
				top : top
			});
		}, null);
		menu.items.append(ditem);
	}
	menu.hover(null, function() {
		$("> .l-menu-over:first", menu).css({
			top : -24
		});
	});
	return menu.css({
		width : '100px'
	}).appendTo('body');
}

2.3、显示菜单


第三步就是绑定右键事件响应函数,这部分代码添加Tab标签页的方法中(addTab方法),而右键事件被绑定在tab上,也就是一个li元素,左键点击该Tab标签用以切换页面显示,右键点击弹出菜单。

// 绑定右键事件
tab.bind('contextmenu', function(e) {
	if (tabEntity.menu) {
		tabEntity.actionTabId = tabitem.id;
		tabEntity.menu.css({
			top : e.pageY,
			left : e.pageX
		}).show();
		if (!tabEntity.tabs[tabEntity.getTabPosision(tabEntity.actionTabId)].closable) {
			 $("> .l-menu-item[menuitemid='close']", tabEntity.menu.items).addClass("l-menu-item-disable");
		} else {
			var closeItem = $("> .l-menu-item[menuitemid='close']", tabEntity.menu.items);
			if (closeItem.hasClass("l-menu-item-disable"))
				closeItem.removeClass("l-menu-item-disable");
		}
	}
	return false;
});

由上面代码可以看出,其实就是将菜单显示在鼠标点击的位置,然后阻止系统默认的右键菜单出现。如果右键事件发生的Tab标签不可关闭,即在添加该标签页时将closable设置为false,那么将“关闭”菜单项设置为禁用状态,反之设置为启用状态。


2.4、菜单项回调


最后就是定义当用户点击弹出菜单的菜单项时的响应函数了,仅仅是根据菜单的不同执行相应的逻辑(或关闭标签或刷新页面)。

代码如下所示:

// 菜单项点击
_menuItemClick: function (menuitem) {
	var tabEntity = this;
	switch (menuitem.id) {
	case 'close':
		this.kill(this.actionTabId);
		this.actionTabId = null;
		break;
	case 'closeother':
		$(this.tabs).each(function () {
			if (tabEntity.actionTabId != this.id) {
				tabEntity.kill(this.id);
			}
		});
		break;
	case 'closeall':
		$(this.tabs).each(function () {
			tabEntity.kill(this.id);
		});
		break;
	case 'reload':
		this.flush(this.actionTabId);
		break;
	default:
		break;
	}
}

至此,整个修改完成,其实也很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值