ES6-标签页组件定制

    了解JavaScript的ES类封装和事件交互机制。
在这里插入图片描述

HTML页面代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/tab.css">
    </link>
</head>

<body>
    <main>
        <h4>
            JS 面向对象 动态添加标签页
        </h4>
        <div class="tabsbox" id="tab">
            <!-- tab标签 -->
            <nav class="firstnav">
                <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="tabcon">
                <section class="conactive">测试1</section>
                <section>测试2</section>
                <section>测试3</section>
            </div>
        </div>
    </main>

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

</html>

CSS样式代码

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


/* 主体盒子 */

main {
    display: block;
    margin: 0 auto;
    margin-top: 100px;
    width: 800px;
    height: 500px;
}


/* 标题 */

main h4 {
    font-weight: 700;
    text-align: center;
    margin-bottom: 15px;
}


/* 标签页盒子 */

main .tabsbox {
    width: 100%;
    height: 480px;
    border: 1px solid #ccc;
}


/* 导航选项 */

main .tabsbox nav {
    display: flex;
    justify-content: space-between;
    border-bottom: 1px solid #ccc;
}

.firstnav {
    height: 50px;
}

main .tabsbox nav ul {
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: row;
}

main .tabsbox nav ul li {
    position: relative;
    width: 100px;
    height: 50px;
    list-style: none;
    text-align: center;
    line-height: 50px;
    border: 1px solid #ccc;
    cursor: pointer;
}


/*被选中的Li的样式*/

.liactive {
    border-bottom: none !important;
}

.iconfont {
    position: absolute;
    right: 0px;
    top: 0px;
    display: inline-block;
    width: 20px;
    height: 20px;
    border: 1px solid #ccc;
    border-radius: 10px;
}

.iconfont::after {
    position: absolute;
    content: "×";
    font-size: 24px;
    top: -15px;
    left: 3px;
    cursor: pointer;
}


/*增加按钮*/

main .tabsbox nav .tabadd {
    align-self: center;
    margin-right: 10px;
    width: 32px;
    height: 32px;
    text-align: center;
    line-height: 32px;
    border: 1px solid #ccc;
}

main .tabsbox nav .tabadd:hover {
    box-shadow: 3px 3px 5px #888888;
    cursor: pointer;
}


/* 内容部分 */

main .tabsbox .tabcon {
    margin: 0;
    padding: 15px;
}

main .tabsbox .tabcon section {
    display: none;
    height: 400px;
}

.conactive {
    display: block !important;
    ;
}

JS脚本控制代码

var _that
class Tab {
    constructor(id) {
        //获取元素
        _that = this
        this.main = document.querySelector(id)
        this.add = this.main.querySelector('.tabadd')
            //获取所有的关闭按钮
            //li的父元素
        this.ul = this.main.querySelector('.firstnav ul:first-child')
        this.fsection = this.main.querySelector('.tabcon')
            //绑定事件
        this.init()
    }
    init() {
            //获取所有的li和section元素
            this.updateNode()
                //初始化事件
            this.add.onclick = this.addTab
            for (let index = 0; index < this.lis.length; index++) {
                this.lis[index].index = index //添加索引号
                this.lis[index].onclick = this.toggleTab //绑定点击函数
                this.removeBtns[index].onclick = this.removeTab //绑定点击函数-删除tab
                this.spans[index].ondblclick = this.editTab //绑定双击函数-编辑edit
                this.sections[index].ondblclick = this.editTab //绑定双击函数-编辑edit
            }
        }
        //获取所有的li和section元素
    updateNode() {
        this.lis = this.main.querySelectorAll('li')
        this.sections = this.main.querySelectorAll('section')
        this.removeBtns = this.main.querySelectorAll('.icon-guanbi')
        this.spans = this.main.querySelectorAll('.firstnav li span:first-child')
    }
    clearClass() {
            //清除class样式
            for (let index = 0; index < this.lis.length; index++) {
                this.lis[index].className = ''
                this.sections[index].className = ''
            }
        }
        //1-切换功能
    toggleTab() {
            console.log(this.index)
                //先清除样式
            _that.clearClass()
                //修改tab标签样式
            this.className = 'liactive'
                //修改显示的内容
            _that.sections[this.index].className = 'conactive'
        }
        //2-添加功能
    addTab() {
            //清除原始元素的样式
            _that.clearClass()
                //创建新的tab
            var li =
                '<li class="liactive"><span>newTab</span><span class="iconfont icon-guanbi"></span></li>'
                //并将其添加父元素中
            _that.ul.insertAdjacentHTML('beforeend', li)
                //创建新的和section
            var section = '<section class="conactive">' + new Date() + '</section>'
                //将其添加到父元素中
            _that.fsection.insertAdjacentHTML('beforeend', section)
                //刷新注册事件
            _that.init()
            console.log('addTab')
        }
        //3-删除功能
    removeTab(e) {
            //阻止事件向上冒泡-防止触发父元素li的点击事件
            e.stopPropagation()
            var index = this.parentNode.index
            console.log(index)
                //根据索引号删除对应的li和section-remove直接删除指定元素
            _that.lis[index].remove()
            _that.sections[index].remove()
                //更新事件
            _that.init()
                //当删除的tab并非出于选中状态,那么原始的选中状态不变
            if (document.querySelector('.liactive')) return
                //当删除选中状态的li时,自动让前一个处于选中状态
            index--
            //主动调用tab标签的点击事件——无需鼠标触发
            _that.lis[index] && _that.lis[index].click()
        }
        //4-修改功能
    editTab() {
        //先获取原始内容
        var str = this.innerHTML
            //双击禁止选中tab和tabpane的文字
        window.getSelection ?
            window.getSelection().removeAllRanges() :
            document.selection.empty
            //双击修改tab和tabpane的文字
        this.innerHTML = '<input type="text" style="width:100%;height:100%"/>'
            //获取文本狂
        var input = this.children[0]
        input.value = str
            //控制文字处于选中状态
        input.select()
            //离开文本框,将文本框的值赋给span标签
        input.onblur = function() {
                this.parentNode.innerHTML = this.value
            }
            //键盘enter时,将文本框的值赋给span标签
        input.onkeyup = function(e) {
            //手动调用鼠标失去焦点事件
            if (e.keyCode === 13) {
                this.blur()
            }
        }
    }
}
//创建Tab对象,自动调用内部成员函数
var tab = new Tab('#tab')

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是席木木啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值