jq页签

版权声明:本文为博主原创文章,转载需注明出处。 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不知道怎么解决= =...

猜你喜欢

转载自blog.csdn.net/AsynSpace/article/details/82255559
JQ2