JavaScript面向对象的程序开发之选项卡Demo讲解——xyp_hf

一、面向对象基础介绍
JS面向对象
JS面向对象

二、写一个面向对象的选项卡
第一步:我先按我们传统的过程式方法写一个选项卡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用面向对象写选项卡</title>
<style>
#div1 div{width:200px;height:200px;border:1px #000 solid;display:none;}
.active{background:red;}
</style>
<script type="text/javascript">
window.onload = function(){
        var oParent = document.getElementById('div1');
        var aInput = oParent.getElementsByTagName('input');
        var aDiv = oParent.getElementsByTagName('div');

        for (var i = 0; i < aInput.length; i++) {
            aInput[i].index = i;
            aInput[i].onclick = function(){
                for (var i = 0; i < aInput.length; i++) {
                    aInput[i].className = '';
                    aDiv[i].style.display = 'none';
                }
                this.className = 'active';
                aDiv[this.index].style.display = 'block';
            };
        }
}
</script>
</head>
<body>
    <div id="div1">
        <input class="active" type="button" value="1">
        <input type="button" value="2">
        <input type="button" value="3">
        <div style="display:block;">11111</div>
        <div>22222</div>
        <div>33333</div>
    </div>
</body>
</html>

第二步:我在看一下上面提到的,刚开始学习面向对象的原则,普通方法变形

// ①将onload中的变量写成全局变量
var oParent = null;
var aInput = null;
var aDiv = null;

window.onload = function(){
        oParent = document.getElementById('div1');
        aInput = oParent.getElementsByTagName('input');
        aDiv = oParent.getElementsByTagName('div');
        // 这里的init函数是初始化函数
        init();
};

// ③ 将onload中不是赋值的语句提取出来,在外面封装成单个的函数,并且在onload中调用
function init(){
    for (var i = 0; i < aInput.length; i++) {
        aInput[i].index = i;
        // ②将嵌套的函数提取出去,封装成单个函数,在原地调用
        aInput[i].onclick = change;
    }
}

function change(){
    for (var i = 0; i < aInput.length; i++) {
        aInput[i].className = '';
        aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[this.index].style.display = 'block';
};

第三步:真正的改成面向对象的程序

// ① 创建一个window.onload创建一个选项卡对象
window.onload = function(){
    // ②起个构造函数的名字叫Tab,注意首字母要大写
    var t1 = new Tab();
    t1.init();
};

// 不管是属性还是方法前面都要加上this
// ③写一个构造函数
function Tab(){
    // ④ 全局变量就是属性
    // 我们在第二步查看一下那些是全局变量,把它们写到这里变形属性
    // 注意:面向对象当中属性前面就是不能加var的
    this.oParent = document.getElementById('div1');
    this.aInput = this.oParent.getElementsByTagName('input');
    this.aDiv = this.oParent.getElementsByTagName('div');
}

// ⑤ 函数就是方法,所以将函数写到构造函数原型的下面
Tab.prototype.init = function() {
    // ⑥在外面建立一个变量,更改this指向
    var This = this;
    for (var i = 0; i < this.aInput.length; i++) {
        this.aInput[i].index = i;
        this.aInput[i].onclick = function(){
            //原本这里的this指向的是this.aInput[i]这个按钮,因此我们要使用⑥的方式,更改this的指向
            This.change(this);
        }
    }
}
// ⑤ 函数就是方法,所以将函数写到构造函数原型的下面
Tab.prototype.change = function(obj) {
    for (var i = 0; i < this.aInput.length; i++) {
        this.aInput[i].className = '';
        this.aDiv[i].style.display = 'none';
    }
    // ⑦ 这里的this也是上面的按钮,因为我们要纠正过来,我可以让上面change函数通过传参将this传递过来
    obj.className = 'active';
    this.aDiv[obj.index].style.display = 'block';
}

// 更改this的原则:尽量让this指向对象

第四步:拓展——面向对象的复用
比如说我们现在有多组选项卡

<div id="div1">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block;">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>
<div id="div2">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block;">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>

// 既然要多次复用,这里我们将id形成参数,让后期可以传进来多次调用

function Tab(id){
    this.oParent = document.getElementById(id);
    this.aInput = this.oParent.getElementsByTagName('input');
    this.aDiv = this.oParent.getElementsByTagName('div');
    this.iNow = 0;
}

//这时候我们我们只要在onload里面在调用一次就可以了,我们发现两个选项卡就立即生效了,这就是面向对象复用性强大的地方

window.onload = function(){
    var t1 = new Tab('div1');
    t1.init();
    var t2 = new Tab('div2');
    t2.init();
};

第五步:面向对象比封装函数更好的一点是它可以很灵活,比如我现在提一个需要,仅让第二的函数自动播放

window.onload = function(){
    var t1 = new Tab('div1');
    t1.init();
    var t2 = new Tab('div2');
    t2.init();
    // 那么我们就给第二个选项卡加一个自动播放
    // 这个方法没有,那么我们就给这个方法去添加这个方法
    t2.autoplay();
};

// 添加自动播放的方法

Tab.prototype.autoplay = function(){
    // 同上面一样,要注意this的指向问题
    var This = this;
    setInterval(function(){
        if (This.iNow == This.aInput.length-1) {
            This.iNow = 0;
        }else{
            This.iNow++;
        }

        for (var i = 0; i < This.aInput.length; i++) {
            This.aInput[i].className = '';
            This.aDiv[i].style.display = 'none';
        }
        This.aInput[This.iNow].className = 'active';
        This.aDiv[This.iNow].style.display = 'block';
    },2000);
};

下面贴身本次demo的全部代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用面向对象写选项卡</title>
<style>
#div1 div,#div2 div{width:200px;height:200px;border:1px #000 solid;display:none;}
.active{background:red;}
</style>
<script type="text/javascript">
/*  
window.onload = function(){
        var oParent = document.getElementById('div1');
        var aInput = oParent.getElementsByTagName('input');
        var aDiv = oParent.getElementsByTagName('div');

        for (var i = 0; i < aInput.length; i++) {
            aInput[i].index = i;
            aInput[i].onclick = function(){
                for (var i = 0; i < aInput.length; i++) {
                    aInput[i].className = '';
                    aDiv[i].style.display = 'none';
                }
                this.className = 'active';
                aDiv[this.index].style.display = 'block';
            };
        }

}
*/

// 变形
/*
var oParent = null;
var aInput = null;
var aDiv = null;

window.onload = function(){
        oParent = document.getElementById('div1');
        aInput = oParent.getElementsByTagName('input');
        aDiv = oParent.getElementsByTagName('div');

        init();

};

function init(){
    for (var i = 0; i < aInput.length; i++) {
        aInput[i].index = i;
        aInput[i].onclick = change;
    }
}

function change(){
    for (var i = 0; i < aInput.length; i++) {
        aInput[i].className = '';
        aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[this.index].style.display = 'block';
};
*/
// 先变型
// 尽量不要出现函数嵌套函数
// 可以有全局变量
// 把onload中不是赋值的语句放到单独函数中

window.onload = function(){
    var t1 = new Tab('div1');
    t1.init();
    var t2 = new Tab('div2');
    t2.init();
    t2.autoplay();
};

function Tab(id){
    this.oParent = document.getElementById(id);
    this.aInput = this.oParent.getElementsByTagName('input');
    this.aDiv = this.oParent.getElementsByTagName('div');

    this.iNow = 0;
}

Tab.prototype.init = function() {
    var This = this;
    for (var i = 0; i < this.aInput.length; i++) {
        this.aInput[i].index = i;
        this.aInput[i].onclick = function(){
            This.change(this);
        }
    }
}

Tab.prototype.change = function(obj) {
    for (var i = 0; i < this.aInput.length; i++) {
        this.aInput[i].className = '';
        this.aDiv[i].style.display = 'none';
    }
    obj.className = 'active';
    this.aDiv[obj.index].style.display = 'block';
}

// 改成面向对象
// 全局变量就是属性
// 函数就是方法
// Onload中创建对象
// 改this指向,(在事件或者定时器中容易改变) 让面向对象中的this指向对象

Tab.prototype.autoplay = function(){
    var This = this;
    setInterval(function(){
        if (This.iNow == This.aInput.length-1) {
            This.iNow = 0;
        }else{
            This.iNow++;
        }

        for (var i = 0; i < This.aInput.length; i++) {
            This.aInput[i].className = '';
            This.aDiv[i].style.display = 'none';
        }
        This.aInput[This.iNow].className = 'active';
        This.aDiv[This.iNow].style.display = 'block';
    },2000);
};


</script>
</head>
<body>
<!-- 
面向对象的选项卡
原则
    - 先写出普通的写法,然后写成面向对象的写法
    >> 普通方法的变型
        尽量不要出现函数嵌套函数
        可以有全局变量
        把onload中不是赋值的语句放到单独函数中
    >> 改成面向对象
    全局变量就是属性
    函数就是方法
    Onload中创建对象
    改this指向问题
 -->
<div id="div1">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block;">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>
<div id="div2">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block;">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>

</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值