JavaScript面向对象编写tab栏

效果图

image.png

功能介绍

1.tab栏内容可以随意切换,且各栏内容对应显示。
2.tab栏右上角叉号可以删除对应的tab栏。
3.点击tab栏左边+号可以实现tab事项的增添。
4.双击tab栏事项或者事项内容可以实施修改操作,回车或者鼠标失去焦点即可以完成修改。

预期改进方案

1.修改后的tab栏文字总像素实时响应修改tab栏的宽度
2.tab栏添加到最右边的时候作是否能继续添加新tab栏事项的判断
3.添加数据本地储存功能

注意事项

1.在编写js代码过程中,要注意this的指向问题
2.执行完某一操作后更新数据

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="css/tab.css" rel="stylesheet" type="text/css">
</head>
<body>
    <h4> js 面向对象 动态添加标签页</h4>
    <div class="tabBox" id="tab">
        <!--        tab标签-->
        <nav class="firstNav">
            <ul>
                <li><span>测试一</span><img src="img/叉号.png"></li>
                <li><span>测试二</span><img src="img/叉号.png"></li>
                <li><span>测试三</span><img src="img/叉号.png"></li>
            </ul>
            <div class="tabAdd">
                <span>+</span>
            </div>
        </nav>
<!--        <br>-->
        <!--        tab内容-->
        <div class="tabContent">
            <section class="content">测试一内容</section>
            <section>测试二内容</section>
            <section>测试三内容</section>
        </div>
    </div>

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

css

h4{
    position: absolute;
    margin-left: 355px;
    margin-top: -42px;
}
.tabBox{
    width: 1200px;
    height: 700px;
    border: 1px solid black;
    margin: 100px auto;
}
.firstNav{
    height: 50px;
    margin-top: -16px;
    border-bottom: 1px solid black;
}
li{
    list-style:none;
    float: left;
    height: 50px;
    border-right: 1px solid black;
}
li span{
    display: block;
    font-size: 15px;
    padding: 13px;
    width: 60px;
    height: 27px;
}
section{
    margin-left: 100px;
    margin-top: 20px;
    font-size: 20px;
}
.tabAdd{
    height: 50px;
    display: block;
}
.tabAdd span{
    width: 32px;
    display: block;
    font-size: 38px;
    position: absolute;
    margin-left: 8px;
    border-right: 1px solid black;
}
section{
    display: none;
}
.content{
    display: block;
}
.current{
    border-bottom: 1px solid white;
}
.current2{
    display: block;
}
img{
    width: 19px;
    height: 15px;
    position: absolute;
    margin-top: -53px;
    margin-left: 66px;
    border-left: 1px solid black;
    border-bottom: 1px solid black;
}

js

var that;
class Tab{
    constructor(id) { // 构造函数,类实例化立马执行
        that = this; // that指向实例化对象
        this.main = document.querySelector(id);
        this.add = this.main.querySelector('.tabAdd span');
        this.ul = this.main.querySelector('ul');
        this.tabContent = this.main.querySelector('.tabContent');
        this.init();
    }
    // 获取(更新)所以的小li和section
    update(){
        this.lis = this.main.querySelectorAll("li");
        this.sections = this.main.querySelectorAll("section");
        this.del = this.main.querySelectorAll('img');
        this.spans = this.main.querySelectorAll("span");
    }
    // 初始化操作函数init
    init(){
        that.update();
        // 将每个li和section绑定索引号
        for (var i = 0; i < this.lis.length; i++){
            this.lis[i].index = i;
            this.sections[i].index = i;
            // 点击调用切换tab栏函数
            this.lis[i].onclick = this.toggleTab; // 此处不能加括号,否则页面一加载就执行
            // 点击叉号删除对应tab栏
            this.del[i].onclick = this.deleteTab;
            // 双击tab栏内容进行修改操作
            this.spans[i].ondblclick = this.editTab;
            // 双击tab栏内容进行修改操作
            this.sections[i].ondblclick = this.editTab;
        }
        // 点击加号调用tab栏添加函数
        this.add.onclick = this.addTab;

    }
    // 切换tab栏
    toggleTab(){
        // 调用清空样式函数clearClass
        that.clearClass(); // 排他思想
        this.className = 'current';
        that.sections[this.index].className = 'current2';
    }
    // 清楚所以li和section的类
    clearClass(){
        for(var i = 0;i < this.lis.length; i++){
            this.lis[i].className = '';
            this.sections[i].className = '';
        }
    }
    // 添加tab栏
    addTab(){
        that.clearClass(); // 先干掉所有人,在创建元素
        var random = Math.random();
        // 创建元素li和section
        var li = '<li><span>新测试</span><img src="img/叉号.png"></li>';
        var tabcon = '<section class="content">新测试内容' + random +'</section>';
        // 添加元素li
        //insertAdjacentHTML支持添加字符串元素,appendChild不支持
        that.ul.insertAdjacentHTML('beforeend',li);
        that.tabContent.insertAdjacentHTML('beforeend',tabcon);
        that.init(); // 更新数据,使新创建的元素支持所有功能
    }
    // 删除tab栏
    deleteTab(e){
        // 防止时间冒泡到父元素li
        e.stopPropagation();
        // 获取当前索引号
        var index = this.parentNode.index;
        console.log(index);
        this.parentNode.remove();
        that.sections[index].remove();
        // 删除操作完成后先更新数据,再进行默认选中操作
        that.init();
        // 如果删除的tab不是当前选定状态,则不做最后一栏默认选定操作
        if(document.querySelector('li')) return ;
        // 先做非空判断,再自动调用tab栏点击事件使删除后的最后一栏默认选中
        that.lis[that.lis.length-1] && that.lis[that.lis.length-1].click();
    }

    // 修改tab栏
    editTab(e){
        // 获取tab栏修改前内容
        var str = this.innerHTML;
        // 双击禁用选中文字
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        // 双击修改span为输入框
        this.innerHTML = '<input type="text" />';
        var input = this.children[0]; // 获取span下的input输入框
        input.value = str; // 将tab栏修改前内容赋给input输入框
        // 将双击后的input输入框文字默认选中
        input.select();
        // input框失去焦点后将input输入框的内容返回给tab栏span
        input.onblur = function () {
            this.parentNode.innerHTML = input.value;
        }
        // 回车将input输入框的内容返回给tab栏span
        input.onkeyup = function (e) {
            if (e.keyCode === 13){
                this.onblur();
            }
        }
    }
}
new Tab('#tab'); // 实例化对象调用Tab类

致读者

有任何意见请联系我

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容