JS- 选项卡(两种方法)之 面向对象 /事件委托

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

效果图

在这里插入图片描述

一.css

<style>
        *{
            margin: 0;
            padding:0;
        }

        ul,ol,li{
            list-style: none;
        }

        .cont{
            width: 800px;
            height: 600px;
            border: 5px solid #333;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }

        .cont ul{
            width: 100%;
            height: 60px;
            display: flex;
        }

        .cont ul li{
            flex:1;
            font-size: 35px;
            color: #fff;
            border-left: 2px solid blue;
            border-right: 2px solid blue;
            background: hotpink;
            display: flex;
            justify-content: center;
            align-items: center;

        }

        .cont ol{
            flex:1;
            position: relative;
        }

        .cont ol li{
            width: 100%;
            height: 100%;
            font-size: 150px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top:0;
            left:0;
            background: burlywood;
            display: none;
        }

        /* 按钮标签 哪个标签有这个属性,哪个就显示特殊背景颜色 */
        .cont ul li.active{
            background: skyblue;
            color: black;
        }

        /* 内容标签 哪个标签有这个属性,哪个就显示 */
        .cont ol li.active{
            display: flex;
        }

    </style>

二.html

<div class="cont">
    <ul>
        <li name="ulli"  class="active">按钮1</li>
        <li name="ulli" >按钮2</li>
        <li name="ulli" >按钮3</li>
    </ul>
    <ol>
        <li name="olli"  class="active">内容1</li>
        <li name="olli" >内容2</li>
        <li name="olli" >内容3</li>
    </ol>
</div>

三.JS方法1:面向过程之事件委托形式

获取父级div标签对象
var oDiv = document.querySelector('div');

// 获取标签对象
var ullis = document.querySelectorAll('ul li');
var ollis = document.querySelectorAll('ol li');
oDiv.onclick = function(e){
    if(e.target.getAttribute('name') === 'ulli'){
        // 1,给所有的li标签,清除样式
        ullis.forEach(function(item,key){
            item.className = '';
            ollis[key].className = '';
            // 给item,也就是ul中的li标签,定义属性
            item.setAttribute('index',key);
        })
        e.target.className = 'active';
        ollis[e.target.getAttribute('index')].className = 'active';
    }         
}

四.JS方法2:面向对象的方法1

创建一个对象,这个对象中有属性有方法
属性是需要操作的标签等
方法就是实现选项卡效果的程序


// 定义构造函数
// 参数:需要执行的tab切换的标签对象,是所有需要执行选项卡效果标签的父级

// 面向对象方法1,建立变量,存储this
function SetTab1(ele){
    // 先要单独,接收存储参数
    this.ele = ele;
    // 通过参数,来获取需要的标签对象
    this.ullis = ele.querySelectorAll('ul li');
    this.ollis = ele.querySelectorAll('ol li');
    // 在构造函数中,定义的this指向的是实例化对象
}
// 定义构造函数的方法
SetTab1.prototype.fun = function(){
    // 选项卡思路
    // 给所有的ul中的li,添加点击事件,点击时,清除所有的ul,ol中li的样式
    // 给当前点击的li,添加样式,再给对应的ol中的li,添加样式
    
    // 定义一个变量,专门存储this指向
    // 此时的this指向,还是 实例化对象
    // oldThis 变量中 存储的就是 实例化对象
    let oldThis = this;

    // 循环遍历 ul中所有的li
    // 这里的 this.ullis 指向的是 实例化对向中的属性 this.ullis 中存储的数据
    // this.ullis   this.ollis   this.ele 其中的this,应该都是指向实例化对象
    this.ullis.forEach(function(item,key){
        // 给 li标签添加点击事件
        item.addEventListener('click' , function(){
            // 在点击事件中,此时this指向的是绑定点击事件的标签 item
            // 就不是 实例化对象了 
            // 此时,要想正确调用 实例化对象属性的属性值
            // 必须 使用 一个 指向是 实例化对象的内容

            // 先循环遍历所有的ul和ol中的li,清除css样式
            oldThis.ullis.forEach(function(item2 , k){
                item2.className = '';
                oldThis.ollis[k].className = '';
            })
            // 给点击的ul,li添加样式
            item.className = 'active';
            // 给对应的ol,li添加样式
            oldThis.ollis[key].className = 'active';
        })
    })
}

wu .JS方法2:面向对象的方法2

// 面向对象方法2,箭头函数
function SetTab2(ele){
    // 先要单独,接收存储参数
    this.ele = ele;
    // 通过参数,来获取需要的标签对象
    this.ullis = ele.querySelectorAll('ul li');
    this.ollis = ele.querySelectorAll('ol li');
    // 在构造函数中,定义的this指向的是实例化对象
}
// 定义构造函数的方法 
// 这里的function不能改为箭头函数,里面的都改
SetTab2.prototype.fun = function(){
    // 将构造函数中,所有的函数,都写成箭头函数
    // this 都会指向父级,最终都指向 实例化对象
    this.ullis.forEach( (item,key)=>{

        // 把普通的函数,改为箭头函数,this指向就是父级程序的this指向
        // 也就是 实例化对象了
        // 如果不改,this指向的是绑定事件的标签,也就是item
        item.addEventListener('click' , ()=>{
            // 这里的forEach也要改为箭头函数,不然this指向的是window
            this.ullis.forEach((item2 , k)=>{
                item2.className = '';
                this.ollis[k].className = '';
            })
            // 给点击的ul,li添加样式
            item.className = 'active';
            // 给对应的ol,li添加样式
            this.ollis[key].className = 'active';
        })
    })
}

// 获取标签对象
const oDiv = document.querySelector('div');

// 通过构造函数,生成实例化对象
// const tabs1 = new SetTab1(oDiv);
// console.log(tabs1)
// 调用实例化对象中的方法,来执行程序,实现选项卡效果
// tabs1.fun();

const tabs2 = new SetTab2(oDiv);
tabs2.fun()




特别注意:
调用构造函数,尤其是封装了方法的构造函数,必须要在定义构造函数之后,来调用
如果先调用,可以调用构造函数,也可以生成实例化对象
实例化对象中,也有属性
但是,对 构造函数 prototype 赋值定义方法,不会提前执行
生成的实例化对象,就没有绑定方法

面向对象语法,最关键的就是this的使用
一定要分清楚,每一个函数中,this的指向
常用  方法1: 找变量,存储this指向
        方法2:function,写成 箭头函数,this为父级程序this
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值