解决方案 »

  1.   

    这是因为在js中没有块级作用域的概念,在js中仅有全局作用域和函数作用域,也就是说你在for中声明的变量i,相当于这样:window.onload = function () {
                var i;
    }好了,上面这个理解后,你试试这段代码:window.onload = function () {
                var arr = document.getElementsByTagName("div");            for (var i = 0; i < arr.length; i++) {
                    arr[i].onclick = function () {
                        console.log(i);
                    };
                }
                console.log('i=',i);
            }
    你会发现console.log这句输出5。好,再往上说,onclick中保存的是一个匿名函数在内存中的位置,也叫指针。
    当你单击的时候,因为onclick中是一个函数指针,所以会去执行,这个时候,你的代码让它去读变量i的值,这时变量i 的值就是真真的5
      

  2.   

    alert(i) 弹出的是0  1   2   3   4 吗?
      

  3.   

    这个其实应该不算是初级问题了,我只能说明问题产生的原因,而无法不用变通手法来解决问题。问题说明:
    很显然,这里的变量i的赋值循环跟事件触发不是同步执行的,事件触发机制是侦听然后触发,所以上面的代码执行完之后,5个div元素侦听其自身的onclick事件,等待鼠标的触发,不触发函数体是不会被执行,而触发之后函数体内的代码执行,此时i就显而易见,不是每个索引值,而是经过循环之后的最终值。自己在写一些事件的时候,有时也会不经意的犯这个错误,避免的思考原则就是把事件执行函数和顺序代码函数分开来看,不要混淆在一起。解决方法:
    直接的解决方法至少目前没有研究过,除非用jquery的object.each(function(i){......}); 上面的i可以按你的需求直接使用,不会受到顺序代码执行后的影响,具体可以去看下jquery的each方法不过如果不套用jquery框架,最能想到的方法就是扩展元素的自定义属性,可以安排div元素的一个自定义属性
    <div nowIndex="1">...</div>
    <div nowIndex="2">...</div>
    <div nowIndex="3">...</div>
    ....
    通过在事件函数中获得该属性后实现。为啥说不是直接解决,自定义属性显而易见不是直接方法,而jquery则要套用该框架所以也不是直接解决。按变量存放原则应该是有书写代码的方法,这里只能抱歉,暂时没有更多时间研究了。
      

  4.   

    这样写,是有点复杂了
    window.onload = function () {            var arr = document.getElementsByTagName("div");            for (var i = 0; i < arr.length; i++) {
                    arr[i].onclick = (function (i) { return (function () { console.log(i); }) })(i);
                }        }
      

  5.   


    <script type="text/javascript">
          
             onload = function(){
                 var div=document.getElementsByTagName("div");
                 for(var i= 0;i<div.length;i++){
                     div[i].addEventListener('click', (function(i){return function() {alert(i);};})(i),false);                   
                     }
                     alert(i);
                 };
        </script>