es6类方法面对对象编程--文本自定义选项卡

es6类方法面对对象编程–文本自定义选项卡案例

效果图

在这里插入图片描述

HTML代码

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>面对对象编程-选项栏案例</title>
</head>

<body>

    <div class="box" id="box">
        <nav class="firstnav">
            <ul>
                <li class="active"><span class="spanText">选项1</span><span class="close">x</span></li>
                <li><span class="spanText">选项2</span><span class="close">x</span></li>
            </ul>
            <div class="add">
                <span>+</span>
            </div>
        </nav>
        <div class="second" id="second">
            <section class="section">内容1</section>
            <section>内容2</section>
        </div>
    </div>


    <script src="main.js"></script>

</body>

</html>

CSS代码


*,
        ul,
        li {
            margin: 0;
            padding: 0;
        }

        .box {
            width: 800px;
            height: 300px;
            border: 1px solid red;
            margin: 50px auto;
        }

        .firstnav {
            width: 100%;
            height: 40px;
            border-bottom: 1px solid #ddd;
            display: flex;
            position: relative;
        }

        ul {
            height: 100%;
            width: 800px;
            font-size: 0;
        }

        ul li {
            list-style: none;
            display: inline-block;
            border-right: 1px solid #ddd;
            height: 40px;
            width: 90px;
            /* margin: 3px 1px; */
            text-align: center;
            position: relative;
            line-height: 38px;
            /* 双击选中文字 */
            -moz-user-select: none;
            /*火狐*/
            -webkit-user-select: none;
            /*webkit浏览器*/
            -ms-user-select: none;
            /*IE10*/
            -khtml-user-select: none;
            /*早期浏览器*/
            user-select: none;
        }

        ul li input {
            font-size: 16px;
            padding: 8px 4px;
            width: 65px;
            border-radius: 5px;
        }

        ul li span {
            font-size: 16px;
        }

        li .close {
            width: 12px;
            height: 12px;
            position: absolute;
            overflow: hidden;
            right: 0px;
            font-size: 12px;
            color: #fff;
            border: 1px solid #333;
            background-color: #333;
            border-radius: 0px 0px 0 13px;
            line-height: 9px;
            text-align: right;
        }

        .active {
            background-color: #ddd;
        }

        .add {
            font-weight: 300;
            font-size: 20px;
            height: 27px;
            width: 27px;
            border: 1px solid #ddd;
            text-align: center;
            position: absolute;
            right: 0;
            margin: 5px;
        }

        .add span {
            text-align: center;
        }

        .second {
            width: 100%;
            height: 258px;
        }

        section {
            width: calc(100% - 40px);
            height: calc(100% - 40px);
            display: none;
            overflow: hidden;
            white-space: pre-wrap
        }


        .section {
            padding: 20px;
            display: block;
        }

        section textarea {
            width: 100%;
            height: 100%;
            text-indent: 20px;
            font-size: 16px;
            resize: none;
        }

javascript代码

let that
class Tab {
    constructor(id) {
        this.add = document.querySelector('.add')
        this.ul = document.querySelector('.firstnav ul')
        this.second = document.querySelector('#second')
        this.add.onclick = this.addTab
        that = this
        this.init()
    }

    init() { // 初始化DOM数据函数
        this.lis = document.querySelectorAll('.firstnav li')
        this.sections = document.querySelectorAll('#second section')
        this.span = document.querySelectorAll('li .close')
        this.span = document.querySelectorAll('li .close')
        this.spanText = document.querySelectorAll('.spanText')

        // 遍历每个DOM元素重置绑定事件
        for (let j = 0; j < this.lis.length; j++) {
            this.lis[j].index = j
            this.lis[j].onclick = this.toggleTab
            this.span[j].onclick = this.deleteTab
            this.spanText[j].ondblclick = this.editTabTitle
            this.sections[j].ondblclick = this.editTabContent
        }
    }

    addEvent() { // 清除元素选中
        for (let i = 0; i < that.lis.length; i++) {
            that.lis[i].className = ''
            that.sections[i].className = ''
        }
    }

    toggleTab() { // 选中特定元素、
        that.addEvent()

        this.className = 'active'
        that.sections[this.index].className = 'section'
    }

    addTab() { // 添加选项卡数量

        // 限制选显卡数量
        if (that.span.length >= 8) return alert('已经最胖了,不要再加了')

        // 获取一个随机数
        let random = Math.random()
        that.addEvent()

        let li = '<li class="active"><span class="spanText">新选项</span><span class="close">x</span></li>'
        let section = '<section class="section">内容' + random + '</section>'

        // 根据选项卡是否为零做出不同判断
        if (that.lis.length !== 0) {
            that.lis[that.lis.length - 1].insertAdjacentHTML('afterend', li)
            that.sections[that.sections.length - 1].insertAdjacentHTML('afterend', section)
        } else {
            that.ul.innerHTML = li
            that.second.innerHTML = section
        }

        that.init()
    }

    deleteTab(e) { // 删除指定选项卡
        e.stopPropagation() // 清除冒泡
        let ins = this.parentNode.index

        // 移除指定选项卡
        this.parentNode.remove()
        that.sections[ins].remove()
        that.init()
        this.active = document.querySelector('.active')

        // 如果删除不是选中元素直接停止执行
        if (this.active) return

        // 判断删除元素和选中是否都为第一个
        if (ins === 0) {
            that.lis[0].className = 'active'
            that.sections[0].className = 'section'
        }

        ins-- // 文件下标减一,判断是否有选中,没有选中则直接选中前一项
        that.lis[ins] && that.lis[ins].click()

    }

    editTabTitle(e) { // 修改选项卡文本
        e.stopPropagation() // 清除冒泡
        this.innerHTML = '<input type="text" value="' + this.innerText + '">'
        this.input = document.querySelector('input')
        this.input.select() // 添加栏出来时,直接选中input中文本

        // 键盘事件enter提交
        this.input.onkeydown = function (e) {

            if (e && e.keyCode === 13) {
                // 因为keydown和blur事件会产生冲突,当执行keydown时也会激活blur事件,
                // 所以在执行键盘事件时先把blur事件取消绑定就不会报错了
                this.onblur = '';

                // call改变this指向
                that.outBlurInput.call(this)

            }
        }
        // 失去焦点直接提交
        this.input.onblur = that.outBlurInput

        console.dir(this);
    }

    editTabContent(e) { // 修改内容文本
        e.stopPropagation() // 清除冒泡
        this.innerHTML = '<textarea>' + this.innerText + '</textarea>'
        this.textarea = document.querySelector('textarea')
        this.textarea = document.querySelector('textarea')
        this.textarea.select() // 添加栏出来时,直接选中textarea中文本

        // 键盘事件enter提交
        this.textarea.onkeydown = function (e) {
            if (e && e.keyCode === 13) {
                // 因为keydown和blur事件会产生冲突,当执行keydown时也会激活blur事件,
                // 所以在执行键盘事件时先把blur事件取消绑定就不会报错了
                this.onblur = '';
                
                // 键盘事件enter提交
                that.outBlurText.call(this)
            }
        }
        // 失去焦点直接提交
        this.textarea.onblur = that.outBlurText
    }

    outBlurInput() { // 限制文本提交长度,并提交
        if (this.value.length > 5) {
            this.parentNode.innerHTML = this.value.substring(0, 5)
            alert('文字长度不能大于5')
        } else if (this.value.length <= 0) {
            this.parentNode.innerHTML = '请填写'
            alert('内容不能为空')
        }
        console.log(this.parentNode);
        this.parentNode.innerHTML = this.value
    }

    outBlurText() { // 提交文本数据
        this.parentNode.innerHTML = this.value
    }
}

let table = new Tab()

 作者:jokerLzg5 
                               							本文禁止转载
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值