版权声明:本文为博主原创文章,转载需注明出处。 https://blog.csdn.net/AsynSpace/article/details/82255559
最近写网页需要用到页签。上网找感觉都还蛮不错,但是,觉得都好多东西,注释又少。看的头疼。所以自己写了一个。放在这当做备忘也给有需要的朋友作为借鉴。
这个页签是用在了管理平台上的。样式很普通,算是勉强能看,比较生硬。基本功能算是有了。也存在一些bug,但是目前不知道怎么去修补。先上个效果图:
就是很普通很大众化的那种。好处是分的比较详细,代码拿来调整一下就可以用。
CSS样式:
<style>
/* 页签样式 */
/* 页签面板 */
.tabPanel{
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
list-style:none;
background-color: #F4F4F4
}
/* 页签默认样式 */
.tabPanel .li{
height: 80%;
padding-left: 10px;
margin-top: 3px;
padding-bottom: 4px;
min-width: 40px;
max-width: 215px;
width: 11%;
float: left;
font-weight: normal;
font-size: 14px;
cursor:pointer;/* 鼠标指向为手型 */
border-right: 1px solid #DFDDDD;/* 设置右边框,用于区分标签 */
}
/* 选中的li标签样式 */
.tabPanel .selectedTab{
background-color: #FFFFFF;
border-bottom: 1px solid #6495ED;
}
/* 页签标题 */
.tabPanel .li-content{
float: left;
max-width: 180px;
width: 80%;
height: 100%;
display:block;
overflow: hidden;
}
/* 页签关闭按钮 */
.tabPanel .li-close{
font-size:16px;
float:right;
height:100%;
min-width: 26px;
width:26px;
text-align:center;
vertical-align:middle;
}
/* 关闭按钮鼠标经过样式 */
.li-close:hover{
color: #ff0033;
}
/* 页签右键菜单样式 */
.rightMenu{
display:none;
font-size: 12px;
width:90px;
height: 101px;
border:1px solid #DFDDDD;
position:absolute;
z-index:100;
margin-left: 10px;
margin-top: 10px;
background-color:#FFFFFF;
}
/* 页签内横线样式 */
.rightMenu hr{
height: 1px;
border: none;
border-top: 1px solid #DFDDDD;
margin: 0px;
padding: 0px;
}
/* 页签右键菜单内部div样式 */
.rightMenu div{
cursor:default;
height: 25px;
/* margin-left: 20px; */
padding-left: 20px;
/* border-left: 1px solid #DFDDDD; */
}
.rightMenu div:hover{
background: rgb(177, 187, 207);
}
/* 页签右键菜单内span样式 */
.rightMenu span{
line-height: 25px;
vertical-align: middle;
/* margin-top: 3px; */
}
</style>
HTML代码:
<!-- 这里是页签导航-->
<div style="padding:0px !important;margin:0px;width:100%;height:100%;overflow:hidden;">
<ul class="tabPanel">
<!-- 动态生成的页签将会出现在这里 -->
</ul>
</div>
<!-- 页面主体内容 -->
<!-- iframe盒子,用于存放所有动态创建的iframe -->
<div id="iframeBox" width="100%">
<iframe id="mainFrame0" width="100%" height="100%" scrolling="true" onclick="menuHide()" frameborder="0"></iframe>
</div>
<!-- 右键菜单div -->
<div id="rightMenu" class="rightMenu">
<div id="mm-tabupdate"><span>刷新</span></div>
<hr id="mm-hr" />
<div id="mm-tabclose"><span>关闭</span></div>
<div id="mm-tabcloseother"><span>关闭其他</span></div>
<div id="mm-tabcloseall"><span>关闭全部</span></div>
</div>
其中mainFrame0是我存放默认的页面的iframe,可根据需要自行删除或保留。
JS代码:
var _iframeIDNum = 1;//iframe计数字段,防止重复
var mainFrame = $("#mainFrame0");//当前iframe
var _tabPanelHtml = [];//用于存放页签的html
var _activeUrl = {url:"/Home/Map"};//用于缓存当前活动页签的属性
var _iframeArr = [{id:"mainFrame0",url:"/Home/Map"}];//用于记录iframe中 id 与 url 对应关系
var _eTargetUrl = '';//当前点击标签对应的URL
///////////////////////////页签
//阻止页签部分的浏览器默认右键点击事件
$(".tabPanel").bind("contextmenu", function(){
return false;
})
//阻止菜单的右键
$("#rightMenu").bind("contextmenu", function(){
return false;
})
//点击时隐藏右键菜单,但点击iframe内无效,故改为下方方法
// $(window).mousedown(function(e){
// if(e.which != 3)
// menuHide();
// });
//鼠标划出右键菜单菜单区域隐藏
$('#rightMenu').mouseleave(function(){//鼠标滑上去
menuHide();
})
//隐藏右键菜单
function menuHide(){
_eTargetUrl = '';//置空当前的选中菜单url
$("#rightMenu").hide();
}
//鼠标点击事件
$(".tabPanel").mousedown(function (e) {
var clickUrl = e.target.onclick.toString().split('"')[1];//获取点击的页签的url
var clientX = e.clientX;//相对于浏览器的x轴坐标
var clientY = e.clientY;//相对于浏览器的y轴坐标
if (e.which == 2) {//鼠标滚轮事件
closeIframe(clickUrl);
_eTargetUrl = '';//置空当前的选中菜单url
}
else if (e.which == 3) {//鼠标右键事件
$("#rightMenu").show();
if(clickUrl != _activeUrl)
{
//如果非当前活动标签,则隐藏刷新选项(刷新非活动页有时会出现刷新后不显示)
$("#rightMenu").height(75);
$('#mm-tabupdate').hide();
$('#mm-hr').hide();
}
else{
$("#rightMenu").height(100);
$('#mm-tabupdate').show();
$('#mm-hr').show();
}
_eTargetUrl = clickUrl;//给当前选中url赋值
//菜单显示位置
$('#rightMenu').css({'left':clientX + 'px','top': clientY + 'px'});
}
})
//菜单项点击事件
$("#rightMenu").mousedown(function (e) {
var noParamUrl = _eTargetUrl.toString().split('?')[0];//无参URL
// 判断点击选项,触发相应事件
if(e.target.innerHTML.indexOf("刷新") > -1 )
{
var ifID = iframeIDByUrl(noParamUrl);//获取点击的页面的ID
$('#' + ifID).attr('src', _eTargetUrl.toString());
}
else if(e.target.innerHTML.indexOf("关闭其他") > -1 )
{
closeIframe(_eTargetUrl,'otherAll');//关闭其他
}
else if(e.target.innerHTML.indexOf("关闭全部") > -1 )
{
closeIframe(_eTargetUrl,'all');//关闭全部
}
else if(e.target.innerHTML.indexOf("关闭") > -1 )
{
closeIframe(noParamUrl);
_eTargetUrl = '';//置空当前的选中菜单url
}
_eTargetUrl = '';//置空当前的选中菜单url
})
//加载指定的页签
function showTabPanel(url){
var html = '';//临时存储html
for(var i in _tabPanelHtml){
//判断页面是否为待显示页面
var tabPanelUrl = $(_tabPanelHtml[i]).find(".li-content").attr("onclick").split('"')[1];//上一个窗口的url
if(UrlCompare(tabPanelUrl, url)){
html += _tabPanelHtml[i].replace("{className}", "selectedTab");//如果为指定的tabPanel,则将其css样式修改为选中后样式
}
else{
html += _tabPanelHtml[i].replace("{className}", "");
}
}
$(".tabPanel").html(html);//更新tabPanel
var liWidth = (_tabPanelHtml.length+1) * $(".li").width();//获取li标签总长度
var winWidth = $(document).width() - 30 ;
//动态修改页签长度
if(liWidth >= winWidth){
var cwidth = winWidth / (_tabPanelHtml.length+2) ;
$(".li").css("width",cwidth);
$(".li-content").css("width",cwidth-27);
}
}
//显示指定iframe
function showIframe(url){
var ifHeight = $(window).height()-$(".main-title").height()-$("#indexTop").height();//非主页下iframe的高度
var iframeHtml = '<iframe id="mainFrame'+_iframeIDNum+'" width="100%" height="100%" scrolling="true" frameborder="0"></iframe>';//iframe的html模板
//隐藏当前显示的iframe
var activeID = '#' + iframeIDByUrl(_activeUrl);
$(activeID).hide();
/////////
showTabPanel(url);//修改页签选中项
//判断当前iframe是否存在,存在则显示,不存在则添加
var u = iframeIDByUrl(url);
_activeUrl = url;//记录活动url
if( u != null)
{
//如果是主页,则单独设置高度
if (u == "mainFrame0")
ifHeight = $(window).height()-$("#indexTop").height();
var id = '#'+ iframeIDByUrl(url);
mainFrame = $(id);//修改mainFrame
mainFrame.height(ifHeight);
}
else{
$("#iframeBox").height($(window).height()-$(".main-title").height()-$("#indexTop").height());//设置iframe的高度
$("#iframeBox").prepend(iframeHtml);
_iframeArr.push({id:"mainFrame"+_iframeIDNum,url:url});
mainFrame = $("#mainFrame"+_iframeIDNum);//修改mainFrame
_iframeIDNum = parseInt(_iframeIDNum) + 1;//iframe的标识数加一
}
//显示当前激活的标签
mainFrame.show();
}
//关闭指定iframe
//url,页面url,无参URL!不能为空!
//closeType关闭类型,默认为null,即关闭单页面
//closeType:all 删除全部,otherAll 删除其他,null 删除当前
function closeIframe(url,closeType){
//如果删除方法为空,调用此处,关闭单页面
if(closeType == null || closeType == undefined || closeType == ''){
$('#' + iframeIDByUrl(url)).remove();
}
//如果关闭方式不为空(删除全部或删除其他)调用此处,删除iframe
if(closeType != null && closeType != undefined && closeType != ''){
if(closeType == 'all'){
for(var ii in _iframeArr){//全部关闭
if(_iframeArr[ii].id == 'mainFrame0') continue;//跳过主页iframe
$('#' + iframeIDByUrl(url)).remove();
}
}
else{
for(var ii in _iframeArr){//关闭其他
if(_iframeArr[ii].id == 'mainFrame0') continue;//跳过主页iframe
if(_iframeArr[ii].url != url){
$('#' + iframeIDByUrl(_iframeArr[ii].url)).remove();
}
}
}
}
//根据判断条件判断_tabPanelHtml中应保留的元素,返回值为True的保留,False的删除
_tabPanelHtml=$.grep(_tabPanelHtml,function(n,i){
if(closeType != null && closeType != undefined && closeType != '')
{
//判断是否为删除全部,如果不是则删除其他
return closeType == 'all' ? false : n.toString().search(url) > -1 ;
}
return n.toString().search(url) == -1;
});
//删除_iframeArr数组中多余元素
_iframeArr=$.grep(_iframeArr,function(n,i){
if(closeType != null && closeType != undefined && closeType != '')
{
if(n.id == 'mainFrame0') return true;//跳过主页iframe
//判断是否为删除全部,如果不是则删除其他
return closeType == 'all' ? false : n.url.toString().search(url) > -1 ;
}
return n.url.toString().search(url) == -1;
});
var tabPanelUrl = _activeUrl;
//判断删除的页是否为当前已激活页,如果是,则将已激活页改为最后打开的页签
if(delFirstSlash(url) == delFirstSlash(_activeUrl) || closeType != null){
var tabPanelHtml = '';//记录对应html
_tabPanelHtml.length > 0 ? tabPanelHtml = _tabPanelHtml[_tabPanelHtml.length-1] : goHome();//如果无页签则返回首页
tabPanelUrl = $(tabPanelHtml).find(".li-content").attr("onclick").split('"')[1];//上一个窗口的url
}
showTabPanel(tabPanelUrl);//重新加载页签
showIframe(tabPanelUrl);//显示对应url页面
}
//根据url查找iframe的ID
function iframeIDByUrl(url){
for(var i in _iframeArr)
{
//判断两个url是否相等,相等则返回iframe的id
if(UrlCompare(_iframeArr[i].url,url))
return _iframeArr[i].id;
}
return null;
}
//删除url开头反斜线
function delFirstSlash(url){
return url.toString().substring(0, 1) == '/' ? url.toString().substring(1, url.length) : url;
}
//判断两个url是否相同,忽略第一个和最后一个‘/’,相同返回true,不同返回false
function UrlCompare(urlA,urlB){
var A = urlA.toString().substring(0,1) == '/' ? urlA.toString().substring(1,urlA.length) : urlA ;
var B = urlB.toString().substring(0,1) == '/' ? urlB.toString().substring(1,urlB.length) : urlB ;
return A == B ? true : false;
}
//菜单点击时触发
function onClick(name, url, pName) {
var noParamUrl = url;//无参url
if (pName == "") {
pName = "首页";
}
//判断url是否有参数,如果有参数则去掉参数信息后再赋值给noParamUrl
if(url.toString().split('?').length > 1){
//设置无参url
noParamUrl = url.toString().split('?')[0];
}
//判断name是否为空,如果不为空则添加页签
if (name.length > 0) {
//查询是否已经创建当前tabPanel
for(var i in _iframeArr){
//判断是否有当前页,如果存在则显示
if(iframeIDByUrl(noParamUrl) != null){
showIframe(noParamUrl);
if(noParamUrl == url)//如果原始url与无参url相等,即无参数,则直接return
return;
//如果原始url与无参url不等,表示有参,则更新iframe的src
mainFrame.attr("src", url);
return;
}
}
var html = "";//存放html代码
html = "<li class='li {className}' title='" + name +"'><span class='li-content' onclick='showIframe(\"{url}\")'>" + name +"</span><a class='li-close' onclick='closeIframe(\"{url}\")'>×</a></li>";
_tabPanelHtml.push(html.replace("{url}",noParamUrl).replace("{url}",noParamUrl));//将当前html添加到tabPanelHtml数组中
}
//如果有参数,则调用无参url
//加载iframe页面、并显示对应TabPanel
showIframe(noParamUrl);
//给iframe追加src
mainFrame.attr("src", url);
}
//返回首页
function goHome() {
$("#iframeBox").height($(window).height()-$("#indexTop").height());//设置iframe的高度
onClick("", "/Home/Map");
}
总结:
样式low,操作low,动画low。只能说算是有个东西了吧。
里面多多少少有一些问题,而且感觉代码还是有点复杂,很多重复的东西。因为不是一次性写完的,后期上级说加东西就懒得改前面的,直接用了。
已知BUG:
1.页签为自动缩小的,但是当到达一定长度后,会缺少一个页签。莫名的被覆盖掉。当继续打开不同的页面,到达一定长度后又会覆盖掉一个。不知道为啥会发生。大概打开十几个页签的时候会发生。
2.iframe的问题。无法监控iframe是否完成加载。
3.这些代码是从项目里拷过来的,可能会有一些小问题,有问题可以留言。目前平台上正常使用,除了上面两个bug不知道怎么解决= =...