幽灵资源网 Design By www.bzswh.com

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

Tab选项卡案例

JS面向对象编程实现的Tab选项卡案例详解

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

<!DOCTYPE html>
<html>
<head>
  <style>
    #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;
    }
  </style>
  <meta charset="utf-8" />
  <title>选项卡</title>
  <script>
    window.onload=function(){
      var tabBox = document.getElementById('tabBox');
      var tabBtn = tabBox.getElementsByTagName('input');
      var tabDiv = tabBox.getElementsByTagName('div');
      
      for(var i=0;i<tabBtn.length;i++){
        tabBtn[i].index = i;
        tabBtn[i].onclick = function (){
          for(var j=0;j<tabBtn.length;j++){
            tabBtn[j].className='';
            tabDiv[j].style.display='none';
          }
          this.className='active';
          tabDiv[this.index].style.display='block';
        };
      }
    };
  </script>
</head>
 
<body>
  <div id="tabBox">
    <input type="button" value="主页" class="active" />
    <input type="button" value="说说" />
    <input type="button" value="日志" />
    <div style="display:block;">这是主页内容</div>
    <div>这是说说内容</div>
    <div>这是日志内容</div>
  </div>
</body>
</html>

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

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

<script>
    //将在嵌套函数里的变量提取到全局中
    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.length;i++){
        tabBtn[i].index = i;
        //此处调用函数即可
        tabBtn[i].onclick = clickBtn;
      }
    };
    
    //将嵌套函数提取到全局中
    function clickBtn(){
      for(var j=0;j<tabBtn.length;j++){
        tabBtn[j].className='';
        tabDiv[j].style.display='none';
      }
      this.className='active';
      tabDiv[this.index].style.display='block';
    };
    
  </script>

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按钮里有这两个属性吗?没有,所以会出错!

JS面向对象编程实现的Tab选项卡案例详解JS面向对象编程实现的Tab选项卡案例详解   

<script>   
    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.length;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.length;j++){
        this.tabBtn[j].className='';
        this.tabDiv[j].style.display='none';
      }
      this.className='active';
      this.tabDiv[this.index].style.display='block';
    }; 
  </script>

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

JS面向对象编程实现的Tab选项卡案例详解

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.length;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.length;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.length;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.length;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.length;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.length;j++){
    this.tabBtn[j].className='';
    this.tabDiv[j].style.display='none';
  }
  btn.className='active';
  this.tabDiv[btn.index].style.display='block';
};

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

<!DOCTYPE html>
<html>
<head>
  <style>
    .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;
    }
  </style>
  <meta charset="utf-8" />
  <title>选项卡</title>
  <!-- 引入tab.js -->
  <script type="text/javascript" src="/UploadFiles/2021-04-02/tab.js">

JS面向对象编程实现的Tab选项卡案例详解

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

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

<!DOCTYPE html>
<html>
  <meta charset="UTF-8" />
  <head>
    <script>
      
      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");
      
    </script>
  </head>
</html>

 解决办法:上面例子中已经列出来了,就是用一个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");

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

标签:
JS,面向对象,Tab选项卡

幽灵资源网 Design By www.bzswh.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
幽灵资源网 Design By www.bzswh.com

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?