Tab栏 面向对象思想(动态增删改查)

HTML部分:

<h4>JS面向对象 动态添加删除标签页</h4>
    <div class="tabsBox" id="tab">
        <nav class="firstNav">
            <ul>
                <li class="liActive">
                    <span>测试1</span>
                    <span class="delete">
                        <img src="img/delete.png" alt="">
                    </span>
                </li>
                <li>
                    <span>测试2</span>
                    <span class="delete">
                        <img src="img/delete.png" alt="">
                    </span>
                </li>
                <li>
                    <span>测试3</span>
                    <span class="delete">
                        <img src="img/delete.png" alt="">
                    </span>
                </li>
            </ul>
            <div class="tabadd">
                <span>
                    <img src="img/add.png" alt="">
                </span>
            </div>
        </nav>
        <!-- tab内容 -->
        <div class="tabsContent">
            <section class="contentActive">测试1</section>
            <section>测试2</section>
            <section>测试3</section>
        </div>
    </div>

CSS部分:

* {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        h4 {
            width: 300px;
            margin: 60px auto;
        }

        .tabsBox {
            width: 700px;
            height: 400px;
            margin: 50px auto;
            border: 2px solid black;
        }

        .firstNav {
            width: 700px;
            height: 41px;
            overflow: hidden;
        }

        .firstNav ul {
            list-style: none;
            float: left;
        }

        .firstNav ul li {
            position: relative;
            float: left;
            padding: 10px 25px;
            border-bottom: 1px solid black;
            background-color: white;
            border-right: 1px solid black;
        }

        .firstNav ul .liActive {
            border-bottom: 1px solid white;
        }

        .tabadd {
            padding: 10px;
            float: right;
        }

        .tabadd img {
            width: 20px;
        }

        .delete {
            position: absolute;
            top: 0;
            right: 0;
            display: block;
            width: 10px;
            height: 10px;
            border-radius: 0 0 0 10px;
            background-color: black;
        }

        .delete img {
            width: 7px;
            float: right;
        }

        .tabsContent section {
            display: none;
        }

        .tabsContent .contentActive {
            display: block;
            width: 696px;
            height: 354px;
            padding: 10px;
            border-top: 1px solid black;
        }

        input {
            width: 100%;
            height: 100%;
        }

JS部分:

window.onload = function () {
    // 定义一个Tab类...
    var that;
    class Tab {
        constructor(id) {
            that = this;
            // 获取元素
            this.main = document.querySelector(id);
            this.add = this.main.querySelector('.tabadd');
            this.ul = this.main.querySelector('.firstNav ul');
            this.tabsContent = this.main.querySelector('.tabsContent');
            // 调用init方法
            this.init();
        }
        // 初始化操作,让相关的元素绑定事件...
        init() {
            // 初始化前获取元素
            this.updateNode();
            // 添加功能..
            this.add.onclick = this.addTab;
            // 切换功能..
            for (var i = 0; i < this.lis.length; i++) {
                // 添加一个属性
                this.lis[i].index = i;
                // 点击时调用函数toggleTab
                this.lis[i].onclick = this.toggleTab;
                // 点击时调用函数removeTab
                this.remove[i].onclick = this.removeTab;
                // 双击时调用函数editTab
                this.spans[i].ondblclick = this.editTab;
                this.sections[i].ondblclick = this.editTab;
            }
        }
        // 更新获取..
        updateNode() {
            this.lis = this.main.querySelectorAll('li');
            this.sections = this.main.querySelectorAll('section');
            this.remove = this.main.querySelectorAll('.delete');
            this.spans = this.main.querySelectorAll('.firstNav li span:first-child');
        }
        // 切换功能...
        toggleTab() {
            // console.log(this.index);
            // 再添加前,先还原其他的
            that.clearClass();
            // 或者添加换下边框的颜色遮住:this.style.borderBottom='1px solid white';
            this.className = 'liActive';
            // section是constructor里的
            that.sections[this.index].className = 'contentActive';
        }
        // 清除功能
        clearClass() {
            for (var i = 0; i < this.lis.length; i++) {
                this.lis[i].className = '';
                this.sections[i].className = '';
            }
        }
        // 添加功能
        addTab() {
            // 再添加前,先还原其他的
            that.clearClass();
            // 创建元素..
            var li = '<li class="liActive"><span>新的选项卡</span><span class="delete"><img src="img/delete.png" alt=""></span></li>'
            var section = ' <section class="contentActive">新的内容...</section>'
            // 将元素动态放到父元素中..
            that.ul.insertAdjacentHTML('beforeend', li);
            that.tabsContent.insertAdjacentHTML('beforeend', section);
            // 添加完后要更新方法事件
            that.init();
        }
        // 删除功能...
        removeTab(event) {
            // 阻止冒泡,防止触发li的切换事件
            event.stopPropagation();
            // 拿到d对应li的索引号
            var index = this.parentNode.index;
            // console.log(index);
            // 删除点击的li和section
            that.lis[index].remove();
            that.sections[index].remove();
            // 删除完完后要更新方法事件
            that.init();
            // 当删除的不是选中状态,则选中的不变,也就是下面的代码不执行
            if (document.querySelector('.liActive')) return;
            // 删除后让前一个li处于选定状态..
            index--;
            that.lis[index] && that.lis[index].click();
        }
        // 修改功能...
        editTab() {
            var str = this.innerHTML;
            // 双击时禁止选定文字
            window.getSelection ? window.getSelection().removeAllRanges() : document.section.empty();
            // 双击时生成文本框
            this.innerHTML = '<input type="text" />';
            // 文本框中保存原有文字
            var input = this.children[0];
            input.value = str;
            // 文本框中的文字处于选中状态
            input.select();
            // 当离开文本框时,把文字给span
            input.onblur = function () {
                this.parentNode.innerHTML = this.value;
            }
            // 按下回车键也可以把文本框中的值给span
            input.onkeyup = function (event) {
                if (event.keyCode === 13) {
                    // 回车键是13,回车相当于调用失去焦点的事件
                    this.blur();
                }
            }
        }
    }
    new Tab('#tab');
}

当类名获取不到时,会出现错误:
index.js:20 Uncaught TypeError: Cannot set property ‘onclick’ of null

在这里插入图片描述

在做完后我想到的小bug:
1.如果添加太多会使选项卡放不下,那么还可以拥有一些折叠功能等
2.添加内容的input框输入文字时只能在一行

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值