我现在还是一个大学生,在做课程设计的时候,要使用到tab页。在网上搜到了好多,但大多都是基于某个框架的。本人虽然能力有限,但还是不太习惯使用别人写好的框架,这样太限制思维了,学不到真正的东西。于是我自己参考了网上的标签页源码,自己做了一个。

  废话不多说,先上张图

  标签页的代码如下:

/*******************************************************************
 * NAME		: 标签页控制器
 *
 * AUTHOR	  : 张琦
 * DATE		: 2011-1-12
 *
 * COMMENT	: 
 * 				纯JavaScript写的标签页控制器。
 *				本标签页控制器要依赖一个数组函数扩展。
 *				要依赖一个CSS样式来定义显示效果,不然本脚本基本上
 *			没有任何效果。
 *				另外,本脚本中用到了“闭包”,所以多数函数都是使用的
 *			内部定义方式,而没有使用原型prototype。
 *******************************************************************/
/**
 @Desc:		标签页
 @Param	{string}	name		标签条面板ID号
 @Param	{string}	title		标签条内容ID号
 @Param	{string}	url			标签条面板ID号
 @Param	{string}	option		标签条内容ID号
 */
function TabPage(name,title,url,option)
{
	var own=this;
	option=option||{};
	option.enable=(option.enable==null?true:option.enable);
	option.closable=(option.closable==null?true:option.closable);
	option.visible=(option.visible==null?true:option.visible);
	own.name=name;		//标签页唯一名称
	own.title=title;	//标签页标题
	own.url=url;		//标签页内容真实路径
	own.enable=option.enable?true:false;		//是否启用
	own.closable=option.closable?true:false;	//是否可关闭
	own.visible=option.visible?true:false;		//是否可视
}

/**
 @Desc:		标签页控制器类定义
 @Param	{string}	barId		标签条面板ID号
 @Param	{string}	contentId	标签条内容ID号
 */
function TabControl(barId,contentId)
{
	var own=this;

	//#region 事件
	/**
	 @Desc:		关闭标签页时的事件
	 @Event:	funtion(srcTab)
	 @Args	{String}	srcTab	将要关闭的标签
	 @Value	{Boolean}	若返回false可阻止关闭
	 */
	own.onClose=null;
	
	/**
	 @Desc:		添加标签页时的事件
	 @Event:	function(name,title,url,option)
	 @Args	{String}	name	待建立标签页唯一标识符
	 @Args	{Number}	title	待建立标签页的标题
	 @Args	{String}	url		待建立标签页内容的实际路径
	 @Args	{Object}	option	待建立标签页设置选项
	 @Value	{Boolean}	若返回false可阻止新建
	 */
	own.onAdding=null;

	/**
	 @Desc:		添加标签页后的事件
	 @Event:	function(name,title,url,option)
	 @Args	{String}	name	待建立标签页唯一标识符
	 @Args	{Number}	title	待建立标签页的标题
	 @Args	{String}	url		待建立标签页内容的实际路径
	 @Args	{Object}	option	待建立标签页设置选项
	 @Value	{Void}		没有作用
	 */
	own.onAdded=null;

	/**
	 @Desc:		选择标签页时的事件
	 @Event:	function(tab,index)
	 @Args	{Object}	tab		将要被选择的标签
	 @Args	{Number}	index	将要被选择的标签页索引
	 @Value	{Boolean}	若返回flase可阻止重新选择标签页
	 */
	own.onSelecting=null;

	/**
	 @Desc:		选择标签页时的事件
	 @Event:	function(tab,index)
	 @Args	{Object}	tab		重新被选择的标签页唯一标识符
	 @Args	{Number}	index	重新被选择的标签页索引
	 @Value	{Void}		没有作用
	 */
	own.onSelected=null;

	/**
	 @Desc:		取消选择标签页时的事件
	 @Event:	function(tab,index)
	 @Args	{Object}	tab		将要被取消选择的标签页唯一标识符
	 @Args	{Number}	index	将要被取消选择的标签页索引
	 @Value	{Boolean}	若返回flase可阻止重新选择标签页
	 */
	own.onDeselecting=null;

	/**
	 @Desc:		取消选择标签页时的事件
	 @Event:	function(tab,index)
	 @Args	{Object}	tab		重新被取消选择的标签页唯一标识符
	 @Args	{Number}	index	重新被取消选择的标签页索引
	 @Value	{Void}		没有作用
	 */
	own.onDeselected=null;

	/**
	 @Desc:		激活标签页索引改变时的事件
	 @Event:	function(oldIndex,newIndex)
	 @Args	{Number}	oldIndex	之前被激活的标签索引
	 @Args	{Number}	newIndex	新近被激活的标签索引
	 @Value	{Void}		没有作用
	 */
	own.onSelectIndexChanged=null;

	/**
	 @Desc:		在标签上点击右键时的事件
	 @Event:	function(tab,index,x,y)
	 @Args	{Object}	tab		被点击的标签
	 @Args	{Number}	index	被点击的标签索引
	 @Args	{Number}	x		点击时鼠标的x坐标
	 @Args	{Number}	y		点击时鼠标的x坐标
	 @Value	{Void}		没有作用
	 */
	own.onContextMenu=null;
	//#endregion

	//#region 字段
	var TabCtrlBar=null;	//控制条容器
	var TabContent=null;	//内容容器
	var objTabPages={};	//标签页对象(对象形式)
	var arrTabPages=[];	//标签页对象(数组形式)
	var	captions={};	//标题对象
	var contents={};	//内容对象
	var selectTab=null;	//当前激活的标签
	var selectIndex=-1;	//当前激活的标签索引
	//#endregion

	//#region 属性
	own.getLength=function()
	{return arrTabPages.length;}
	
	own.getSelectIndex=function()
	{return selectIndex;}
	own.setSelectIndex=function(val)
	{own.select(val);}
	
	own.getSelectTab=function()
	{return selectTab;}
	own.setSelectTab=function(val)
	{own.select(val);}
	//#endregion

	//#region 处理
	/**
	 @Desc:		处理标签上单击事件
	 */
	function handleCaptionClick(name)
	{
		var sleTab=getTab(name);
		if(sleTab.enable)
			this.select(name);
	}
	function handleCloseClick(name)
	{
		if(this.getLength()<=1)
		{
			alert("最后一个标签不允许关闭!");
			return;
		}
		var sleTab=getTab(name);
		if(sleTab.enable&&sleTab.closable)
		{
			var sleIndex=this.getSelectIndex();
			this.remove(name);
			if(sleIndex<this.getLength())
				this.select(sleIndex);
			else
				this.select(sleIndex-1);
		}
	}
	function handleCaptionDblClick(name)
	{
		var sleTab=getTab(name);
		if(sleTab.enable)
			this.refresh(name);
	}
	//#endregion

	//#region 方法
	/**
	 @Desc:		真正的构造初始化函数
	 @Param	{string}	barId		标签条面板ID号
	 @Param	{string}	contentId	标签条内容ID号
	 */
	function init(barId,contentId)
	{
		var TitleTable = document.createElement("table");
		TitleTable.cellPadding=0;
		TitleTable.cellSpacing=0;
		var titleBody = document.createElement("tbody");
		var titleRow = document.createElement("tr");
		titleBody.appendChild(titleRow);
		TitleTable.appendChild(titleBody);
		document.getElementById(barId).appendChild(TitleTable);
		
		TabCtrlBar=titleRow;
		TabContent=document.getElementById(contentId);
	}

	/**
	 @Desc:		创建标签页标题
	 @Param	{String}	name	标签条面板ID号
	 @Param {String}	title	标签条标题
	 */
	function createCaption(name,title)
	{
		var TabCaption = document.createElement("table");
		TabCaption.id="TabCaption_"+name;TabCaption.name="TabCaption_"+name;
		TabCaption.className="TabPage_Caption";
		TabCaption.cellPadding=0;TabCaption.cellSpacing=0;
		var tbCaption = document.createElement("tbody");
		var trCaption = document.createElement("tr");
		//不显示内容,只显示背景图片,为了使标签显示完整
		var tdLeft = document.createElement("td");
		tdLeft.className = "tabPage_Left";
		//作为标题显示
		var tdMid = document.createElement("td");
		tdMid.innerText = title;
		tdMid.className = "tabPage_Middle";
		tdMid.title = "双击刷新该页";
		//不显示内容,只显示背景图片,为了使标签显示完整
		var tdRight = document.createElement("td");
		tdRight.className = "tabPage_Right";
	
		//作为关闭按纽的容器
		var tdClose = document.createElement("td");
		tdClose.className = "tabPage_Middle";
		//建立关闭按纽
		var closeBtn = document.createElement("span");
		closeBtn.id = "btn"+name;
		closeBtn.title = "关闭此标签";
		closeBtn.className = "tabPage_CloseBlur";
		closeBtn.innerHTML="  ";
		tdClose.appendChild(closeBtn);
		
		trCaption.appendChild(tdLeft);
		trCaption.appendChild(tdMid);
		trCaption.appendChild(tdClose);
		trCaption.appendChild(tdRight);
		tbCaption.appendChild(trCaption);
		TabCaption.appendChild(tbCaption);
		
		closeBtn.onmouseover=function(){this.className="tabPage_CloseFocus";};
		closeBtn.onmouseout=function(){this.className="tabPage_CloseBlur";};
		closeBtn.onclick=function(){handleCloseClick.call(own,name);};
		
		return TabCaption;
	}

	/**
	 @Desc:		创建标签页标题
	 @Param	{String}	name	标签条面板ID号
	 @Param {String}	url		标签页实际内容路径
	 */
	function createContent(name,url)
	{
		var iFrame=document.createElement("iframe");
		iFrame.id="TabContent_"+name;iFrame.name="TabContent_"+name;
		iFrame.frameBorder=0;iFrame.className="tabPage_Frame";
		if(url!=null)iFrame.src=url;
		return iFrame;
	}

	function getTab(tab)
	{
		var page=null;
		//索引数字
		if((typeof tab=="number")||(Object.prototype.toString(tab)=="[object Number]"))
		{page=arrTabPages[tab];}
		//唯一标识字符串
		else if((typeof tab=="string")||(Object.prototype.toString(tab)=="[object String]"))
		{page=objTabPages[tab];}
		else
		{}
		return page;
	}

	/**
	 @Desc:		添加标签页
	 @Param	{String}	name	标签条面板ID号
	 @Param {String}	title	标签条标题
	 @Param {String}	url		标签页实际内容路径
	 @Param {Object}	option	标签页设置选项
	 			enable	{Boolean}	是否启用
	 			closable{Boolean}	是否可关闭
	 			visible	{Boolean}	是否可视
	 @Return	{Number}		创建标签页结果
	 			-2		已有同名标签页
	 			-1		触发事件禁止创建此标签页
	 			0-n		新建标签页的索引号
	 */
	function add(name,title,url,option)
	{
		if(objTabPages[name])
			return -2;
		if(own.onAdding)	//触发onAdding事件
			if(!own.onAdding.apply(own,arguments))
				return -1;
		//创建标题条
		var Caption=createCaption(name,title);
		var Bar = document.createElement("td");
		Bar.className="tabPage_Blur";
		Bar.appendChild(Caption); 
		TabCtrlBar.appendChild(Bar);
		//创建内容项
		var Content=createContent(name,url);
		TabContent.appendChild(Content);
		//添加到内部数组中
		captions[name]=Bar;
		contents[name]=Content;
		var tab=new TabPage(name,title,url,option);
		objTabPages[name]=tab;
		arrTabPages.push(tab);
		//绑定标签事件
		Caption.onselectstart=function(){return false;};
		Caption.onclick=function(){handleCaptionClick.call(own,name);};
		Caption.ondblclick=function(){handleCaptionDblClick.call(own,name);};
		Caption.oncontextmenu=function(){if(own.onContextMenu)own.onContextMenu.call(own,objTabPages[name],arrTabPages.indexOf(objTabPages[name]),event.x,event.y);return false;};
		
		if(own.onAdded)		//触发onAdded事件
			own.onAdded.apply(own,arguments);
		return arrTabPages.length-1;
	}

	/**
	 @Desc:		选择标签页
	 @Param	{Number|String}	tab	标签页序号({Number})或标签页名称({String})
	 */
	function select(tab)
	{
		var newTab=getTab(tab);
		if(newTab==selectTab)return;	//如果新选择的标签和原选择的标签相同,则返回
		var newIndex=arrTabPages.indexOf(newTab);
		if(newTab&&-1!=newIndex)
		{
			if(own.onDeselecting)		//触发onDeselecting事件
				if(!own.onDeselecting(selectTab,selectIndex))
					return;
			if(own.onSelecting)			//触发onSelecting事件
				if(!own.onDeselecting(newTab,newIndex))
					return;
			try
			{
				captions[selectTab.name].className="TabPage_Blur";
				contents[selectTab.name].style.display="none";
			}
			catch(ex){}
			finally
			{
				captions[newTab.name].className="TabPage_Focus";
				contents[newTab.name].style.display="block";
			}
			if(own.onDeselected)		//触发onDeselected事件
				own.onDeselecting(selectTab,selectIndex);
			if(own.onSelected)			//触发onSelected事件
				own.onSelected(newTab,newIndex);
			if(own.onSelectIndexChanged)//触发onSelectIndexChanged事件
				own.onSelectIndexChanged(selectIndex,newIndex);
			selectTab=newTab;			//记录所选择的标签页
			selectIndex=newIndex;		//记录所选择的标签页序号
		}
	}

	/**
	 @Desc:		添加标签页,并选择新添加的标签页
	 @Param	{String}	name	标签条面板ID号
	 @Param {String}	title	标签条标题
	 @Param {String}	url		标签页实际内容路径
	 @Param {Object}	option	标签页设置选项
	 			enable	{Boolean}	是否启用
	 			closable{Boolean}	是否可关闭
	 			visible	{Boolean}	是否可视
	 @Return	{Number}		创建标签页结果
	 			-2		已有同名标签页
	 			-1		触发事件禁止创建此标签页
	 			0-n		新建标签页的索引号
	 */
	function selectAdd(name,title,url,option)
	{
		own.add(name,title,url,option);
		own.select(name);
	}

	/**
	 @Desc:		移除标签页
	 @Param	{Number|String}	tab	标签页序号({Number})或标签页名称({String})
	 */
	function remove(tab)
	{
		var oldTab=getTab(tab);
		if(oldTab)
		{
			TabCtrlBar.removeChild(captions[oldTab.name]);
			TabContent.removeChild(contents[oldTab.name]);
			arrTabPages.remove(oldTab);
			delete objTabPages[oldTab.name];
			var newIndex=arrTabPages.indexOf(selectTab);
			if(selectIndex!=newIndex)
			{
				if(own.onSelectIndexChanged)//触发onSelectIndexChanged事件
					own.onSelectIndexChanged(selectIndex,newIndex);
				this.setSelectIndex(newIndex);
			}
		}
	}

	/**
	 @Desc:		刷新标签页
	 @Param	{Number|String}	tab	标签页序号({Number})或标签页名称({String})
	 */
	function refresh(tab)
	{
		var sleTab=getTab(tab);
		if(sleTab)
		{
			contents[sleTab.name].src="about:blank";
			contents[sleTab.name].src=objTabPages[sleTab.name].url;
		}
	}

	/**
	 @Desc:		启用标签页
	 @Param	{Number|String}	tab	标签页序号({Number})或标签页名称({String})
	 */
	function enable(tab)
	{
		var enTab=getTab(tab);
		if(enTab)
		{
			captions[enTab.name].disabled=false;
			enTab.enable=true;
		}
	}

	/**
	 @Desc:		禁用标签页
	 @Param	{Number|String}	tab	标签页序号({Number})或标签页名称({String})
	 */
	function disable(tab)
	{
		var disTab=getTab(tab);
		if(disTab)
		{
			captions[disTab.name].disabled=true;
			disTab.enable=false;
		}
	}
	//#endregion
	
	//#region 导出表
	own.add=add;
	own.select=select;
	own.selectAdd=selectAdd;
	own.remove=remove;
	own.refresh=refresh;
	own.enable=enable;
	own.disable=disable;
	//#endregion
	
	//调用初始化方法
	init(barId,contentId);
}
标签页的样式表如下:
/*
.TabPage_Caption	标签页一个完整标题的表格
.tabPage_Blur		标签页失去焦点时的样式
.tabPage_focus		标签页获得焦点时的样式
	.tabPage_Left		标签页的标签左半部分
	.tabPage_Middle	标签页的标签中部
	.tabPage_Right		标签页的标签右半部分
.tabPage_Frame		标签页实际内容框架
*/
.tabPage_Left, .tabPage_Middle, .tabPage_Right
{
	border: 0;
	margin: 0;
	padding: 0;
	height:25px;
}
.tabPage_Middle
{
	font-size:12px;
	font-weight:bold;
	text-indent: 2px;
	padding-right:3px;
	cursor: default;
}
.tabPage_Blur .tabPage_Left
{
	background : url("tabpage/tabblur.gif");
	background-position:left bottom;
	width:5px;
}
.tabPage_Blur .tabPage_Middle
{
	background : url("tabpage/midblur.gif"); 
	color: #2F79C1;
	padding-top: 4px;
}
.tabPage_Blur .tabPage_Right
{
	background : url("tabpage/tabblur.gif");
	background-position:right bottom;
	width:5px;
}
.tabPage_Focus .tabPage_Left
{
	background : url("tabpage/tabfocus.gif");
	background-position:left bottom;
	width:5px;
}
.tabPage_Focus .tabPage_Middle
{
	background : url("tabpage/midfocus.gif"); 
	color: #000000;
	padding-top: 0px;
}
.tabPage_Focus .tabPage_Right
{
	background : url("tabpage/tabfocus.gif");
	background-position:right bottom;
	width:5px;
}
.tabPage_CloseBlur
{
	cursor: hand;
	background-image: url(tabpage/closeblur.gif);
	background-repeat: no-repeat;
	background-position: 1px 4px;
	width: 14px;
	height: 20px;
}
.tabPage_CloseFocus
{
	cursor: hand;
	background-image: url(tabpage/closefocus.gif);
background-position: 0px 3px; width: 14px; height: 20px; } .tabPage_Frame { width: 100%; height: 100%; margin: 0; padding: 0; border: 1px solid gray; overflow: auto; display: none; }
调用方法
<html>
	<head>
		<title>TabPage测试页</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
		<meta http-equiv="Page-Exit" content="revealTrans(Duration=1.0,Transition=13)">
		<link rel="stylesheet" href="tabpage.css">
	</head>
	<body>
		<table id="mainFrame" cellspacing="0" cellpadding="0" width="100%" height="100%">
			<tr>
				<td id="tabTT" height="25px"></td>
			</tr>
			<tr>
				<td id="tabCC"></td>
			</tr>
		</table>
<script language="javascript" src="extend.js"></script>
<script language="javascript" src="tabpage.js"></script>
<script language="javascript">
var tab=new TabControl("tabTT","tabCC");
tab.onContextMenu=function(tab,index,x,y){alert(tab.title+index+","+x+","+y)};
tab.add("google","咸阳师范学院内网论坛","http://127.0.0.1/bbs");
tab.selectAdd("jwc","咸阳师范学院教务处","http://127.0.0.1");
//window.setTimeout(function(){tab.remove("dd23")},4000)
</script>
</body>
</html>