面向对象版TAB栏

面向对象版的tab栏
 
功能要点:
1.点击添加按钮可以增加一个新标签和内容;
2.点击Tab标签上的删除按钮可以删除对应的标签和内容;
3.点击Tab可以切换Tab栏
4.双击Tab名称和内容可以变成输入框,失去焦点和回车可以改变对应内容。
 
页面结构:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>面向对象 Tab</title>
    <link rel="stylesheet" href="./styles/tab.css">
    <link rel="stylesheet" href="./styles/style.css">
</head>
<body>
    <main>
        <h4>
            Js 面向对象 动态添加标签页
        </h4>
        <div class="tabsbox" id="tab">
            <!-- tab 标签 -->
            <nav class="fisrstnav">
                <ul>
                    <li class="liactive"><span>测试1</span><span class="iconfont icon-guanbi"></span></li>
                    <li><span>测试2</span><span class="iconfont icon-guanbi"></span></li>
                    <li><span>测试3</span><span class="iconfont icon-guanbi"></span></li>
                </ul>
                <div class="tabadd">
                    <span>+</span>
                </div>
            </nav>

            <!-- tab 内容 -->
            <div class="tabscon">
                <section class="conactive">测试1</section>
                <section>测试2</section>
                <section>测试3</section>
            </div>
        </div>
    </main>

    <script src="js/tab.js"></script>
</body>
</html>

 

CSS样式:

* {
    margin: 0;
    padding: 0;
}
ul li {
    list-style: none;
}
main {
    width: 960px;
    height: 500px;
    border-radius: 10px;
    margin: 50px auto;
}
main h4 {
    height: 100px;
    line-height: 100px;
    text-align: center;
}
.tabsbox {
    width: 900px;
    margin: 0 auto;
    height: 400px;
    border: 1px solid lightsalmon;
    position: relative;
}
nav ul {
    overflow: hidden;
}
nav ul li {
    float: left;
    width: 100px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border-right: 1px solid #ccc;
    position: relative;
}
nav ul li.liactive {
    border-bottom: 2px solid #fff;
    z-index: 9;
}
#tab input {
    width: 80%;
    height: 60%;
}
nav ul li span:last-child {
    position: absolute;
    user-select: none;
    font-size: 12px;
    top: -18px;
    right: 0;
    display: inline-block;
    height: 20px;
}
.tabadd {
    position: absolute;
    /* width: 100px; */
    top: 0;
    right: 0;
}
.tabadd span {
    display: block;
    width: 20px;
    height: 20px;
    line-height: 20px;
    text-align: center;
    border: 1px solid #ccc;
    float: right;
    margin: 10px;
    user-select: none;
}
.tabscon {
    width: 100%;
    height: 300px;
    position: absolute;
    padding: 30px;
    top: 50px;
    left: 0px;
    box-sizing: border-box;
    border-top: 1px solid #ccc;
}
.tabscon section,
.tabscon section.conactive {
    display: none;
    width: 100%;
    height: 100%;
}
.tabscon section.conactive {
    display: block;
}

 tab.js

//定义类
var that;
class Tab {
    constructor(id) {
        that = this;
        //根据传入的ID获取最外层包裹元素
        this.main = document.querySelector(id);
        this.ul = this.main.querySelector('.firstnav>ul');
        this.tabscon = this.main.querySelector('.tabscon');
        this.tabadd = this.main.querySelector('.tabadd');
        this.init();
    }
    getE() { //获取元素
        this.Ali = this.main.querySelectorAll('li');
        this.Asection = this.main.querySelectorAll('section');
        this.Aguanbi = this.main.querySelectorAll('.icon-guanbi');
        this.Aspan = this.main.querySelectorAll('li>span:first-child');
    }
    clearClass() { //切换时清楚样式
        for (var i = 0; i < this.Ali.length; i++) {
            this.Ali[i].className = '';
            this.Asection[i].className = '';
        }
    }
    init() {
        //为增加按钮的点击事件绑定增加方法
        this.tabadd.onclick = this.addTab;
        //由于每次初始化之前都需要查询到最新的DOM,所以需要先调用该方法;
        this.getE();
        //锚定li的数量顺序,分别为:
        //1、li的点击事件绑定切换方法;
        //2、关闭按钮的点击事件绑定删除方法;
        //3、li的第一个span的双击事件绑定编辑方法;
        //4、section的双击事件绑定编辑方法。
        for (var i = 0; i < this.Ali.length; i++) {
            this.Ali[i].index = i; //为li定义index属性。
            this.Ali[i].onclick = this.toggleTab; //li的点击事件绑定切换方法;
            this.Aguanbi[i].onclick = this.removeTab; //关闭按钮的点击事件绑定删除方法;
            this.Aspan[i].ondblclick = this.editTab; //3、li的第一个span的双击事件绑定编辑方法;
            this.Asection[i].ondblclick = this.editTab; //4、section的双击事件绑定编辑方法。
        }
    }
    addTab() { //增加Tab
        //添加内容之前先把其它标签选中状态清除掉
        that.clearClass();
        //第一步先生成新的li和section
        var li = '<li class="liactive"><span>新选项卡</span><span class="iconfont icon-guanbi"></span></li>'; //新的LI
        var section = '<section class="conactive">新内容' + Math.random(); + '</section>'; //新的section。
        //第二部将前面生成的li和section追加到ul和Asection
        that.ul.insertAdjacentHTML('beforeend', li);
        that.tabscon.insertAdjacentHTML('beforeend', section);

        //重新初始化
        that.init();
    }
    removeTab(e) { //删除一个Tab
        //阻止点击事件冒泡
        e.stopPropagation();
        //锚定当前关闭按钮的父节点li的index属性。
        var index = this.parentNode.index;
        //先删除当前关闭按钮所在的li和对应的section。
        that.Ali[index].remove();
        that.Asection[index].remove();
        //删除以后需要初始化一下
        that.init();
        //查询当前是不是还有.liactive,如果有就什么都不干。
        if (document.querySelector('.liactive')) {
            return;
        }
        //再判断,如果INDEX大于0则让INDEX=0,否则INDEX减一
        index = index > 0 ? index-- : 0;
        //让INDEX等于INDEX的li点击一下
        that.Ali[index].click();
    }
    toggleTab() { //Tab切换
        //第一步要把LI和SECTION的选中状态都去除
        that.clearClass();
        //把当前LI变成选中状态,把对应INDEX的SECTION变成选中状态
        this.className = 'liactive';
        that.Asection[this.index].className = 'conactive';
    }
    editTab() { //双击后编辑内容
        console.log(111);
        //暂存当前元素的INNERHTML到字符串
        var str = this.innerHTML;
        //禁止双击选中文字
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        //将当前元素变成INPUT
        this.innerHTML = '<input type=text />';
        var input = this.children[0];
        //将字符串STR拷贝给INPUT的VALUE
        input.value = str;
        //使INPUT的VALUE处于选中状态
        input.select();

        //当INPUT失去焦点时
        input.onblur = function() {
                this.parentNode.innerHTML = this.value;
            }
            //当用户点击ENTER时
        input.onkeyup = function(e) {
            if (e.keyCode === 13) {
                this.blur();
            }
        }
    }
}

// 实例化一个对象
new Tab('#tab');

 

 

posted on 2021-04-27 19:29  前端码牛  阅读(167)  评论(0)    收藏  举报

导航