本文实例讲述了JS面向对象编程实现的Tab选项卡。分享给大家供大家参考,具体如下:

Tab选项卡案例

html5 原生选择组件 html5选项卡_构造函数

下面是一个简单面向过程的Tab选项卡。

#tabBox input {

background: #F6F3F3;

border: 1px solid #FF0000;

}

#tabBox .active {

background: #E9D4D4;

}

#tabBox div {

width:300px;

height:250px;

display:none;

padding: 10px;

background: #E9D4D4;

border: 1px solid #FF0000;

}

选项卡


window.οnlοad=function(){

var tabBox = document.getElementById('tabBox');

var tabBtn = tabBox.getElementsByTagName('input');

var tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

tabBtn[i].index = i;

tabBtn[i].onclick = function (){

for(var j=0;j

tabBtn[j].className='';

tabDiv[j].style.display='none';

}

this.className='active';

tabDiv[this.index].style.display='block';

};

}

};



这是主页内容



这是说说内容



这是日志内容



下面来慢慢改成面向对象的形式。

1.首先将嵌套的函数拿到window.onload外面,不能有函数嵌套,可以有全局变量。如下:所有的改写最终效果都不变。

//将在嵌套函数里的变量提取到全局中

var tabBtn = null;

var tabDiv = null;

window.onload = function(){

var tabBox = document.getElementById('tabBox');

tabBtn = tabBox.getElementsByTagName('input');

tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

tabBtn[i].index = i;

//此处调用函数即可

tabBtn[i].onclick = clickBtn;

}

};

//将嵌套函数提取到全局中

function clickBtn(){

for(var j=0;j

tabBtn[j].className='';

tabDiv[j].style.display='none';

}

this.className='active';

tabDiv[this.index].style.display='block';

};

2.将全局的变量变为对象的属性,全局的函数变为对象的方法;将window.onload里的代码提取到一个构造函数里面,在window.onload里创建对象即可;(下面的代码执行起来是有问题的)。

这里必须注意:在构造函数Tab里的this跟之前this所代表的是不同的(此处是通过new来创建对象的);在上面的示例中,this指的是调用者;在构造函数里,this指向的是var tab = new Tab() ,即tab这个对象,注意是对象。

说一下这段代码的问题:我们在Tab的原型上添加clickBtn方法后,clickBtn方法里的this本应该是指向var tab = new Tab()的,但是我们在 this.tabBtn[i].onclick = this.clickBtn; 将clickBtn添加给了this.tabBtn[i],即input按钮,clickBtn的所属由Tab对象变成了input按钮。

clickBtn的所属变成input按钮后,那么clickBtn里的this指向按钮,那再来看clickBtn里的代码,this.tabBtn、this.tabDiv,input按钮里有这两个属性吗?没有,所以会出错!

html5 原生选择组件 html5选项卡_构造函数_02

html5 原生选择组件 html5选项卡_html5 原生选择组件_03

window.onload = function(){

var tab = new Tab("tabBox");

}

/**

* 将之前window.onload里的代码提到一个构造函数里

* [可以将这个Tab构造函数想象成一个Tab类]

* @param {Object} id:选项卡id以参数的形式传入

*/

function Tab(id){

var tabBox = document.getElementById(id);

//将之前的全局变量变为对象的属性

this.tabBtn = tabBox.getElementsByTagName('input');

this.tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

this.tabBtn[i].index = i;

//此处这种方式调用函数,已经将clickBtn的所属变成this.tabBtn[i]

this.tabBtn[i].onclick = this.clickBtn;

}

};

//将之前的全局函数添加到构造函数的原型里,作为对象的一个方法

Tab.prototype.clickBtn = function(){

alert(this); //HTMLInputElement

for(var j=0;j

this.tabBtn[j].className='';

this.tabDiv[j].style.display='none';

}

this.className='active';

this.tabDiv[this.index].style.display='block';

};

3.将clickBtn的调用放在一个函数里,这样就不会改变clickBtn的所属了。alert(this);此时弹出的是一个Object,说明clickBtn的所属关系没变,还是Tab对象。但是还有另一个问题,此时clickBtn里的this指向tab对象,那么this.className、this.index,此处的this指的是tab对象,那么对象中有这两个属性吗?没有,还会出错!所以第4步继续改造。

html5 原生选择组件 html5选项卡_面向对象_04

window.onload = function(){

var tab = new Tab("tabBox");

}

/**

* 选项卡

* @param {Object} id:选项卡id

*/

function Tab(id){

var tabBox = document.getElementById(id);

this.tabBtn = tabBox.getElementsByTagName('input');

this.tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

this.tabBtn[i].index = i;

//将this保存成一个变量,就可以在下面代码中调用对象的方法了

var _this = this;

//此处这种方式调用函数,就不会改变clickBtn方法的所属关系

this.tabBtn[i].onclick = function(){

//注意此处不能直接使用this,this指向this.tabBtn[i]

_this.clickBtn();

};

}

};

//点击选项卡按钮

Tab.prototype.clickBtn = function(){

alert(this); //Object

for(var j=0;j

this.tabBtn[j].className='';

this.tabDiv[j].style.display='none';

}

this.className='active';

this.tabDiv[this.index].style.display='block';

};

4. 以参数的形式将点击的按钮传入clickBtn中

window.onload = function(){

var tab = new Tab("tabBox");

}

/**

* 选项卡

* @param {Object} id:选项卡id

*/

function Tab(id){

var tabBox = document.getElementById(id);

this.tabBtn = tabBox.getElementsByTagName('input');

this.tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

this.tabBtn[i].index = i;

var _this = this;

this.tabBtn[i].onclick = function(){

//注意参数this代表的是this.tabBtn[i],即input按钮

_this.clickBtn(this);

};

}

};

//将点击的按钮以参数的形式传入

Tab.prototype.clickBtn = function(btn){

for(var j=0;j

this.tabBtn[j].className='';

this.tabDiv[j].style.display='none';

}

btn.className='active';

this.tabDiv[btn.index].style.display='block';

};

5.最终版 —— 将代码提取到一个单独的js文件中,在用的时候引入即可。一般花大时间去写一个面向对象的程序,就是为了能够复用,以及方便的使用。

Tab.js

/**

* 选项卡

* @param {Object} id 选项卡id

*/

function Tab(id){

var tabBox = document.getElementById(id);

this.tabBtn = tabBox.getElementsByTagName('input');

this.tabDiv = tabBox.getElementsByTagName('div');

for(var i=0;i

this.tabBtn[i].index = i;

var _this = this;

this.tabBtn[i].onclick = function(){

_this.clickBtn(this);

};

}

};

/**

* 为Tab原型添加点击选项卡方法

* @param {Object} btn 点击的按钮

*/

Tab.prototype.clickBtn = function(btn){

for(var j=0;j

this.tabBtn[j].className='';

this.tabDiv[j].style.display='none';

}

btn.className='active';

this.tabDiv[btn.index].style.display='block';

};

使用:tab.html 可以看到使用的时候,就可以很简单的创建两个选项卡出来了。

.tab input {

background: #F6F3F3;

border: 1px solid #FF0000;

}

.tab .active {

background: #E9D4D4;

}

.tab div {

width:300px;

height:250px;

display:none;

padding: 10px;

background: #E9D4D4;

border: 1px solid #FF0000;

}

选项卡


window.onload = function(){

var tab1 = new Tab("tabBox1");

var tab2 = new Tab("tabBox2");

}



这是主页内容



这是说说内容



这是日志内容



Js、Vue



VSCode



CSDN



html5 原生选择组件 html5选项卡_面向对象_05

再来简单总结一下JS面向对象中的this,this一般会在两种情况下出问题,一是使用定时器、二是事件,从上面的例子中也可以看出来。注意下面的说法是在构造函数里哦,其它情况下,this指向的是调用者。

可以看到效果没有将姓名显示出来,其实看到这里原因应该很清楚了,就是第14行代码中this.name,此处的this指向谁?指向window,因为setInterval是属于window的。

function Person(name){

this.name = name;

//定时器

setInterval(this.showName, 3000);

}

Person.prototype.showName = function(){

alert(this); //window

alert("姓名:"+this.name);

}

var p1 = new Person("jiangzhou");

解决办法:上面例子中已经列出来了,就是用一个function将要执行的代码包起来,使其所属关系不会发生变化,注意function里调用方法时使用的是外部变量'_this'。事件的处理在上面的例子中已经说明了。

function Person(name){

this.name = name;

var _this = this;

setInterval(function(){

this.showName();

}, 3000);

}

Person.prototype.showName = function(){

alert(this); //[Object Object]

alert("姓名:"+this.name); //姓名:jianghzou

}

var p1 = new Person("jiangzhou");