问答详情
源自:10-1 编程挑战

求助,关于for循环中的函数

 for(var i= 0,len = xli.length;i<len;i++){

xxx(i);

}

function xxx(i){

xli[i].onclick=function(){

for(var n= 0;n<len;n++){

                         xli[n].className = "";

                         xDivs[n].className = "cont";

}

xli[i].className = "on";

xDivs[i].className="";

   }

}

如上代码是可行的。但是将xxx这个函数替换掉xxx(i)位置就不可行了。什么原因呢?

提问者:Original121 2016-05-02 14:40

个回答

  • kuban
    2016-05-03 11:52:33
    已采纳

    for(var i= 0,len = xli.length;i<len;i++){

       xli[i].onclick=function(){

           for(var n= 0;n<len;n++){

               xli[n].className = "";

               xDivs[n].className = "cont";

           }

           xli[i].className = "on";

           xDivs[i].className="";

       }

    }这是你想改成的代码吧


    先说一下for循环的时候做了什么吧,给每一个li绑定了一个onclick事件,然后for循环就结束了


    ,到这里一切都正常


    问题出在onclick触发时,


    xli[i].className = "on";


    xDivs[i].className="";


    执行上述2个语句,i是多少,由于本身onclick事件绑定的匿名函数里没有i的相关定义,按照作


    用域链,向上一级查找i,这时在for循环里找到i的定义,此时i是多少呢,由于for循环早就跑完


    了,onclick事件也早绑完了,所以i是len-1,到此,就错误了。


    那么提问那种方法为什么没错,因为把i作为参数,在传参的过程中给保存了,每一个li对应的i


    值都被保存了,保存在函数xxx的参数i里,防止2个i你分不清楚,我给改写一下你看的明白。


    function xxx(obj){//参数obj保存了当时i的值


    xli[i].onclick=function(){//绑定事件时,i向上从for循环里取当时的i值


    for(var n= 0;n<len;n++){


                             xli[n].className = "";


                             xDivs[n].className = "cont";


    }


    xli[obj].className = "on";//触发事件后,找obj的值,向上一级查找,找到参数obj,值为当时i的



    xDivs[obj].className="";



       }


    到此,就是说,想要不出现i值错误,就要保存一下i值,上面那种作为参数保存是一种,标准答


    案提供的是另一种


    for(var i= 0,len = xli.length;i<len;i++){

       xli[i].obj=i;//给li自定义了一个obj属性,保存当时的i值,每一个li都有一个obj属性,来


    保存对应的i值

      xli[i].onclick=function(){

           for(var n= 0;n<len;n++){

               xli[n].className = "";

              xDivs[n].className = "cont";

          }

           this.className = "on";//this为触发onclick的li

           xDivs[this.obj].className="";//this.obj值为触发onclick的li当时的i值

      }

    }


    还有很多种方法,比如i值保存在函数属性里,比如i值保存在一个局部变量里,重点都在于把每


    个li对应的i值给保存住,js有一个重要知识点叫做闭包,也可以用来保存i值,这里不做多讲,


    可以自己查询了解一下。


  • 遇见你是我美丽的意外
    2016-06-23 22:23:23

    这时在for循环里找到i的定义,此时i是多少呢,由于for循环早就跑完


    了,onclick事件也早绑完了,所以i是len-1,到此,就错误了。

    就是这句话,不是很明白。。。

  • 遇见你是我美丽的意外
    2016-06-23 22:17:00

    for(var i= 0,len = xli.length;i<len;i++){

       xli[i].onclick=function(){

           for(var n= 0;n<len;n++){

               xli[n].className = "";

               xDivs[n].className = "cont";

           }

           xli[i].className = "on";

           xDivs[i].className="";

       }

    }这是你想改成的代码吧

    这个i并没有执行完吧,都是从0开始的呀。xli[0],xli[1]....依次往后的呀

  • kuban
    2016-05-03 15:00:08

    <!DOCTYPE html>
    <html>
    <head lang="en">
       <meta charset="UTF-8">
       <title></title>
    </head>
    <body>
    for循环内的i值:<input class="f1" /><br>
    for循环外的i值:<input class="f2" />
    <script>
       (function a(){
           for(var i=0;i<5;i++)
           {
               var f1=document.getElementsByClassName("f1");
               f1[0].value=i;
           }
           var f2=document.getElementsByClassName("f2");
           f2[0].value=i;
       })();
    </script>
    </body>
    </html>