简单的tab开发解析

使用下面的几种方法都可以实现我们想要的效果。下面我一一进行描述讲解下。
首先我们需要弄清楚一个问题,下面的代码(方法0:)为什么不可以实现我们想要的效果,而且逻辑上好像也没有什么问题。

方法0:

for (var i = 0;i < tabList.length; i++){
        tabList[i].onclick = function () {
            console.dir(this);
            changeTabHandle(i);
        }  
}

如果想弄懂这个问题我们需要知道函数在浏览器中的操作原理。函数操作分为2个阶段:函数创建和函数执行。

【函数创建】会经历下面几个过程。

  1. 函数属于引用类型的,首先会开辟一个堆内存,把函数体中的代码当作字符串存储在这个对内存中,为了找到这个内置,浏览器会为其分配一个16进制的地址。在我们上面的代码中会把“console.dir(this);changeTabHandle(i);”存储在对内存中。
  2. 把开辟的堆内存的16进制的地址赋值给函数名。

【函数执行】会经历下面几个过程。

  1. 函数执行首先会形成一个私有的作用域(栈内存)
  2. 把之前存储在堆内存中的代码字符串复制一份过来,变成js代码,从上到下依次执行。

方法0不可行的原因是,进入循环体后,把字符串拷贝到堆内存中,i依然在加1,当点击按钮出发函数执行的时候,1已经变成了tabList.length.既然知道了原因,那怎么解决这个问题呢?我们依次来看下面几个方法。

方法1-3中使用的changeTabHandle函数

//n 当前点击按钮的索引
function changeTabHandle(n) {
    for(var i=0; i<tabList.length; i++){
        tabList[i].className = '';
        divList[i].className = '';
    }
    tabList[n].className = 'active';
    divList[n].className = 'active'; 
}
  1. 自定义属性名

    //方法一:自定义属性方法,把当前的i存在我们获取的对象上面。让对象的一个属性(_f_index)把当前按钮的索引保存下来。
    console.log(tabList);
    for (var i = 0;i < tabList.length; i++){

       tabList[i]._f_index = i;
       tabList[i].onclick = function () {
           console.dir(this);
           changeTabHandle(this._f_index);
       }  

    }

  2. es6 let

    //方法二:var --> let,利用了es6中let块级作用域的概念。
    for(let i=0; i<tabList.length; i++){

       tabList[i].onclick = function() {
           changeTabHandle(i);
       }

    }

  3. 闭包
    //下面2个方法都是利用了闭包的保存作用。闭包有2个作用一个是保护其私有作用域的私有变量不受外界干扰,另一个作用就是可以保存以下内容。

下面几种方法都可以让函数自制行
(function(){})()
~function()()
!function()()
+function()()
方法一:

for(var i=0; i<tabList.length; i++){
     ~function (i) {
         tabList[i].onclick = function () {
             changeTabHandle(i);
         }
     }(i)
 }

方法二:

 for(var i=0; i<tabList.length; i++){
     tabList[i].onclick = function (i) {
         return function() {
             changeTabHandle(i);
         }
     }(i)
 }
  1. 记忆上次是那个被选中而不是全部清空+自定义属性

    beforeIndex = 0;
    for(var i=0; i<tabList.length; i++){

    tabList[i]._f_index = i;
    tabList[i].onclick = function() {
        
        tabList[beforeIndex].className = '';
        divList[beforeIndex].className = '';
        tabList[this._f_index].className = 'active';
        divList[this._f_index].className = 'active';
        beforeIndex = this._f_index;
    }

    }

5.记忆上次是那个被选中而不是全部清空+let

for(let i=0; i<tabList.length; i++){
    tabList[i].onclick = function (params) {
        tabList[beforeIndex].className = '';
        divList[beforeIndex].className = '';
        tabList[i].className = 'active';
        divList[i].className = 'active';
        beforeIndex = i;
    }
}

github 实例代码 https://github.com/fung-yu/js... 中的tab篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值