做一个后台管理系统tab标签功能

前言

因为以前会经常在一些后台系统中看到这种tab功能,如下:(随便截得一个图)
做一个后台管理系统tab标签功能_第1张图片
刚好我也想做点东西,我就想着自己能不能写出来,项目地址在后面

需求分析

1、技术

因为我一开始是自己查的资料,然后很多资料都指向jquery ui,但是因为是自己造一个,所以我就看了一下他的写法。

2、功能

1、左边点击新增页面和tab标签(不能重复添加)
2、tab标签过多会自动隐藏并且左侧点击后平滑到视野范围内
3、tab标签有左右移动、点击选中当前页

拆分

目录
ajax_tabs--|
           |--index.html (暂定版)                  
           |--index1_1.html (左侧新增页面功能拆分)
           |--index1.html (原始左侧新增)
           |--index2_1.html (tab滑动功能拆分)
           |--index2.html (tab滑动原始)
           |--index3.html (失败版)
           |--nav1.html
           |--nav2.html
           |--nav3.html
           |--nav4.html
           |--nav5.html

html布局

<style>
    * {
        margin: 0;
        padding: 0;
    }

    li {
        list-style: none;
    }

    a {
        text-decoration: none;
    }

    .warp {
        width: 50%;
        height: 400px;
        margin: 20px auto;
        border: 1px solid #ccc;
        display: flex;
    }

    .left,
    .right {
        height: 100%;
        box-sizing: border-box;
    }

    .left {
        border-right: 1px solid #ccc;
        width: 200px;
        padding: 20px;
    }

    .right {
        width: calc(100% - 200px)
    }

    .topNav {
        height: 50px;
        border-bottom: 1px solid #ccc;
    }

    .topNav li {
        width: 3rem;
        height: 50px;
        display: inline-block;
        overflow: hidden;
        line-height: 50px;
    }
    .content>div.active{
        display:block;
    }
    .content>div{
        display:none;
    }
    .topNav li>a.active,.navItem>a.active{
        color:red;
    }
style>
<div class="warp">
    <div class="left">
        <ul>
            <li class="navItem">
                <a href="javascript:void(0)" data-value="./nav1.html">导航1a>
            li>
            <li class="navItem">
                <a href="javascript:void(0)" data-value="./nav2.html">导航2a>
            li>
            <li class="navItem">
                <a href="javascript:void(0)" data-value="./nav3.html">导航3a>
            li>
        ul>
    div>
    <div class="right">
        <div class="topNav">
            <ul id="topNav">
                
            ul>
        div>
        <div class="content" id="content">

        div>
    div>
div>
1、左侧点击新增页面

index1_1.html

 //初始化 首页或者什么页
 var tabs = (function(){
     //存储已打开的页面
     let tabList = [];

     //命名 右上角id  内容块id,导航li的类名
     function tabs(obj){
         this.contentId = obj.contentId;
         this.tabId = obj.tabId;
         this.navClass = obj.nav;
     }
     //初始化
     tabs.prototype.init = function(){
         let elClass = '.' + this.navClass;
         let el = $(elClass).eq(0).find('a')
         this.addTo(el)
     }

     //添加新内容 
     tabs.prototype.addTo = function(el){
         $(el).addClass('active').parent().siblings().find('a').removeClass('active')
         let url = $(el).attr('data-value');
         let text = $(el).text();
         let index = url.lastIndexOf('/');
         let item = url.substring(index + 1, url.length - 5);
         let idName = 'tab_' + item;
         //防止添加失败
         for(var i = 0,l=tabList.length;iif(tabList[i] == idName){
                 this.sameNav(idName)
                 return;
             }
         }
         //存储已存在的
         tabList.push(idName); 
         this.addContent(idName,url,text);
     }
     //添加内容
     tabs.prototype.addContent = function(idName,url,text){
         //添加tab选项
         $('#'+this.tabId).find('a').removeClass('active')
         $('#'+this.tabId).append(`
  • "tabNav">"#" class="${idName} active " data-value="${idName}">${text}
  • `) //其余内容隐藏 $('#'+this.contentId).children().removeClass('active') //添加主内容 $('#'+this.contentId).append(`
    "${idName}" class="active">
    `); $('#'+idName).load(url); }, //点击已存在的tab tabs.prototype.sameNav = function(idName){ $('#'+idName).addClass('active').siblings().removeClass('active') $('.'+idName).addClass('active').parent().siblings().find('a').removeClass('active'); } return tabs; })(); var test = new tabs({contentId:'content',tabId:'topNav',nav:'navItem'}) test.init(); $('.navItem>a').bind('click', function () { test.addTo(this); }); $('body').on('click', '.tabNav>a', function (e) { if($(this).hasClass('activ')){ return; } let idName = $(this).attr('data-value'); test.sameNav(idName) e.stopPropagation(); // 阻止事件冒泡 e.preventDefault(); // 阻止默认行为 })

    效果
    做一个后台管理系统tab标签功能_第2张图片

    2、tab左右滑动点击

    造假数据

    <ul id="topNav">
       <li class="tabNav">
            <a href="#" class="">导航一a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航二a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航三a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航一一a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航一二a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航一三a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航二一a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航二二a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航二三a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航三一a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航三二a>
        li>
        <li class="tabNav">
            <a href="#" class="">导航三三a>
        li>
    ul>

    index2_1.html

    var tabScrool = (function () {
        let key = 0;
        let itemInfo = {
            tabW: '',//tab内容块的宽度
            itemNum: '',//标签个数
            length: '',//标签总长度
            itemIndex: '',//当前完整显示的最右边的index值
            itemShowNum: '', //能够完整显示几个
        }
    
        function tabScrool() {
    
        }
        tabScrool.prototype.init = function () {
            let tabW = parseFloat($('.topNav').width()) //获取tab内容块的宽度
            let itemNum = $('#topNav li').length; //标签个数
            let length = 0; //标签总长度
            let itemIndex = itemNum; //标签页能够完整第几个
            $('#topNav li').each(function () {
                if (length < tabW) {
                    length += Math.ceil(parseFloat($(this).outerWidth()));
                    if (length > tabW) {
                        itemIndex = $(this).index();
                    }
                }else{
                    length += Math.ceil(parseFloat($(this).outerWidth()));
                }
            })
            // console.log(tabW, itemNum, length, itemIndex)
            if (itemIndex < itemNum && key == 0) {
                $('#left').show();
                $('#right').show()
                $('.topNav').css('padding', '0 20px');
                $('.topNav ul').css('left', '25px');
                key = 1;
                this.init(); //重新计算
            } else {
                itemInfo.tabW = tabW;
                itemInfo.itemNum = itemNum;
                itemInfo.length = length;
                itemInfo.itemIndex = itemIndex-1;
                itemInfo.itemShowNum = itemIndex;
                // console.log(tabW, itemNum, length, itemIndex)
                if(key == 1){
                    l = itemInfo.length - itemInfo.tabW;
                    // console.log(l)
                    let left = l - 20;
                    $('.topNav ul').css('left', -left);
                    itemInfo.itemIndex = itemInfo.itemNum -1;
                    // console.log(itemInfo.itemIndex)
                }
            }
        }
        //获取从0到index直接tab的宽度
        tabScrool.prototype.getLength = function(index){
            let length =0;
            for(let i = 0;i<=index;i++){
                length += Math.ceil(parseFloat($('#topNav li').eq(i).outerWidth()));
            }
            let left = length -itemInfo.tabW -20;
            if(left<0){
                left = -25
            }
            return left;
        }
        tabScrool.prototype.goDir = function(dir){
            itemInfo.itemIndex = dir == 'left' ? --itemInfo.itemIndex : ++itemInfo.itemIndex
            if(itemInfo.itemIndex>=itemInfo.itemNum){
                // console.log(1)
                itemInfo.itemIndex = itemInfo.itemNum-1;
                return false;
            }else if(itemInfo.itemIndex+1 < itemInfo.itemShowNum){
                // console.log(2)
                itemInfo.itemIndex = itemInfo.itemShowNum;
                return false;
            }
            let left = this.getLength(itemInfo.itemIndex);
            $('.topNav ul').css('left', -left);
            console.log(itemInfo.itemIndex)
        }
        tabScrool.prototype.goIndex = function(index){
            // console.log(index)
    
            if(index +1 >=itemInfo.itemNum){
                itemInfo.itemIndex = itemInfo.itemNum-1;
            }else if(index == 0){
                itemInfo.itemIndex = itemInfo.itemShowNum-1;
            }else if(itemInfo.itemIndex - index  >=  itemInfo.itemShowNum){
                let offset = itemInfo.itemIndex - index - itemInfo.itemShowNum +1
                itemInfo.itemIndex = itemInfo.itemIndex - offset;
            }else{
                itemInfo.itemIndex = index;
            }
            let left = this.getLength(itemInfo.itemIndex);
            $('.topNav ul').css('left', -left);
        }
        return tabScrool;
    })()
    var tabTop = new tabScrool();
    tabTop.init();
    
    
    $('.tabNav a').bind('click', function () {
        let index = $(this).parent().index();
        //tab点击
        tabTop.goIndex(index)
    })
    //按钮绑定
    $('#left').bind('click', function () {
        tabTop.goDir('left')
    })
    $('#right').bind('click', function () {
        tabTop.goDir('right')
    })

    效果
    做一个后台管理系统tab标签功能_第3张图片

    整合

    index.html

    这里就两点,一个是将tab初始放在添加新页面方法里面;一个是左侧点击,如果已存在标签,则标签会平滑到视野内。

    var tabScrool = (function () {
        let key = 0;
        let itemInfo = {
            tabW: '',//tab内容块的宽度
            itemNum: '',//标签个数
            length: '',//标签总长度
            itemIndex: '',//当前完整显示的最右边的index值
            itemShowNum: '', //能够完整显示几个
        }
    
        function tabScrool() {
    
        }
        tabScrool.prototype.init = function () {
            let tabW = parseFloat($('.topNav').width()) //获取tab内容块的宽度
            let itemNum = $('#topNav li').length; //标签个数
            let length = 0; //标签总长度
            let itemIndex = itemNum; //标签页能够完整第几个
            $('#topNav li').each(function () {
                if (length < tabW) {
                    length += Math.ceil(parseFloat($(this).outerWidth()));
                    if (length > tabW) {
                        itemIndex = $(this).index();
                    }
                }else{
                    length += Math.ceil(parseFloat($(this).outerWidth()));
                }
            })
            // console.log(tabW, itemNum, length, itemIndex)
            if (itemIndex < itemNum && key == 0) {
                $('#left').show();
                $('#right').show()
                $('.topNav').css('padding', '0 20px');
                $('.topNav ul').css('left', '25px');
                key = 1;
                this.init(); //重新计算
            } else {
                itemInfo.tabW = tabW;
                itemInfo.itemNum = itemNum;
                itemInfo.length = length;
                itemInfo.itemIndex = itemIndex-1;
                itemInfo.itemShowNum = itemIndex;
                // console.log(tabW, itemNum, length, itemIndex)
                if(key == 1){
                    l = itemInfo.length - itemInfo.tabW;
                    // console.log(l)
                    let left = l - 24;
                    $('.topNav ul').css('left', -left);
                    itemInfo.itemIndex = itemInfo.itemNum -1;
                    // console.log(itemInfo.itemIndex)
                }
            }
        }
        //获取从0到index直接tab的宽度
        tabScrool.prototype.getLength = function(index){
            let length =0;
            for(let i = 0;i<=index;i++){
                length += Math.ceil(parseFloat($('#topNav li').eq(i).outerWidth()));
            }
            let left = length -itemInfo.tabW -24;
            if(left<0){
                left = -25
            }
            return left;
        }
        tabScrool.prototype.goDir = function(dir){
            itemInfo.itemIndex = dir == 'left' ? --itemInfo.itemIndex : ++itemInfo.itemIndex
            if(itemInfo.itemIndex>=itemInfo.itemNum){
                // console.log(1)
                itemInfo.itemIndex = itemInfo.itemNum-1;
                return false;
            }else if(itemInfo.itemIndex+1 < itemInfo.itemShowNum){
                // console.log(2)
                itemInfo.itemIndex = itemInfo.itemShowNum;
                return false;
            }
            let left = this.getLength(itemInfo.itemIndex);
            $('.topNav ul').css('left', -left);
            console.log(itemInfo.itemIndex)
        }
        tabScrool.prototype.goIndex = function(index){
            // console.log(index)
    
            if(index +1 >=itemInfo.itemNum){
                itemInfo.itemIndex = itemInfo.itemNum-1;
            }else if(index == 0){
                itemInfo.itemIndex = itemInfo.itemShowNum-1;
            }else if(itemInfo.itemIndex - index  >=  itemInfo.itemShowNum){
                let offset = itemInfo.itemIndex - index - itemInfo.itemShowNum +1
                itemInfo.itemIndex = itemInfo.itemIndex - offset;
            }else{
                itemInfo.itemIndex = index;
            }
            let left = this.getLength(itemInfo.itemIndex);
            $('.topNav ul').css('left', -left);
        }
        return tabScrool;
    })()
    var tabTop = new tabScrool();
    
    //初始化 首页或者什么页
    var tabs = (function () {
        //存储已打开的页面
        let tabList = [];
        //命名 右上角id  内容块id,导航li的类名
        function tabs(obj) {
            this.contentId = obj.contentId;
            this.tabId = obj.tabId;
            this.navClass = obj.nav;
        }
        //初始化
        tabs.prototype.init = function () {
            let elClass = '.' + this.navClass;
            let el = $(elClass).eq(0).find('a')
            this.addTo(el)
        }
    
        //添加新内容 
        tabs.prototype.addTo = function (el) {
            $(el).addClass('active').parent().siblings().find('a').removeClass('active')
            let url = $(el).attr('data-value');
            let text = $(el).text();
            let index = url.lastIndexOf('/');
            let item = url.substring(index + 1, url.length - 5);
            let idName = 'tab_' + item;
            //防止添加失败
            for (var i = 0, l = tabList.length; i < l; i++) {
                if (tabList[i] == idName) {
                    this.sameNav(idName)
                    tabTop.goIndex(i)
                    return;
                }
            }
            //存储已存在的
            tabList.push(idName);
            this.addContent(idName, url, text);
    
            //计算tab宽度
            tabTop.init();
        }
        //添加内容
        tabs.prototype.addContent = function (idName, url, text) {
                //添加tab选项
                $('#' + this.tabId).find('a').removeClass('active')
                $('#' + this.tabId).append(
                    `
  • "tabNav">"#" class="${idName} active " data-value="${idName}">${text}
  • ` ) //其余内容隐藏 $('#' + this.contentId).children().removeClass('active') //添加主内容 $('#' + this.contentId).append(`
    "${idName}" class="active">
    `); $('#' + idName).load(url); }, //点击已存在的tab tabs.prototype.sameNav = function (idName) { $('#' + idName).addClass('active').siblings().removeClass('active') $('.' + idName).addClass('active').parent().siblings().find('a').removeClass('active'); } return tabs; })(); var test = new tabs({ contentId: 'content', tabId: 'topNav', nav: 'navItem' }) test.init(); $('.navItem>a').bind('click', function () { test.addTo(this); }); $('#left').bind('click', function () { tabTop.goDir('left') }) $('#right').bind('click', function () { tabTop.goDir('right') }) $('body').on('click', '.tabNav>a', function (e) { if ($(this).hasClass('activ')) { return; } let idName = $(this).attr('data-value'); test.sameNav(idName) let index = $(this).parent().index(); //tab点击 tabTop.goIndex(index) e.stopPropagation(); // 阻止事件冒泡 e.preventDefault(); // 阻止默认行为 })

    效果
    做一个后台管理系统tab标签功能_第4张图片

    至此,一个小demo出现了,不过还有不足,比如标签页的删除,不过我觉得这是小问题了(手动笑脸)

    项目:ajax_tabs
    演示:ajax_tabs

    你可能感兴趣的:(大前端-javascript)