zoukankan      html  css  js  c++  java
  • js之常见问题--for循环中为什么点击总是弹出最后一个i

    首先看看点击不同li标签时,弹出li的索引值对应的结果

    HTML:

    <ul>
    <li>0</li>
    <li>2</li>
    <li>2</li>
    <li>3</li>
    </ul>

    JS:

    for(var i = 0; i < aLi.length; i++){
    aLi[i].onclick = function(){
    alert(i);
    }
    }

    运行结果不尽人意,发现点击li后都是返回4,我们分析一下代码,

    当i = 0时,aLi[0].onclick = function(){alert(i)}

    当i = 1时,aLi[1].onclick = function(){alert(i)}

    当i = 2时,aLi[1].onclick = function(){alert(i)}

    当i = 3时,aLi[1].onclick = function(){alert(i)}

    当i = 4时,不满足条件跳出循环

    在执行click的函数的时候,会有一个作用域链,这个作用域链是一个对象列表,这组对象定义了代码作用域中的变量。( 可以详细了解一下变量对象的内容)当我们alert(i)的时候,会去从内到外的去寻找变量i。这个时候这个函数的作用域链上有4个对象,这时循环已经结束了,i此时的值为4.所以点击任何一个li,弹出的都是4,而不是我们想要的索引值。

    那么问题来了,我们为了解决这个问题我们需要做的是每次给aLi[i]绑定事件的时候,将这个时候i的值保存在内部的作用域中

    方法一:使用闭包的形式

    for(var i= 0;i<aLi.length;i++){
    (function(i){
    aLi[i].onclick=function(){
    alert(i)
    }
    })(i)
    }

    这里涉及到一个块级作用域的概念。在es6出来之前,函数是作为创建块级作用域的主要手段。这里我们通过在aLi[i].onclick外面套上一层函数,将i作为参数,然后重新分析一下结果。

    i = 0时,
    (function(i){
    aLi[0].onclick = function(){
    alert(i);
    }
    })(0)
    i = 1时,
    (function(i){
    aLi[1].onclick = function(){
    alert(i);
    }
    })(1)
    (function(i){
    aLi[2].onclick = function(){
    alert(i);
    }
    })(2)
    (function(i){
    aLi[3].onclick = function(){
    alert(i);
    }
    })(4)
    i = 4时,不满足条件跳出循环.

    由于多了一层自执行函数的包裹,当我们点击li时,会有三层的作用域,从内带外分别是:click函数内部的变量对象,自执行函数的变量对象和最外层的window对象。查找到第二层的时候,找到了i,自执行函数的i等于传入的参数值,相对应的存下了当时i的值,所以就弹出了相应的索引值

    方法二:使用ES6中的新特性let来声明变量

    for(let i=0;i<aLi.length;i++){
    aLi[i].onclick = function(){
    alert(i)
    }
    }

    方法三:引入jquery,使用其中的on或delegate进行事件绑定(它们都有事件代理的特性)

    $("ul").on("click", "li", function(){
    var index = $(this).index();
    var info = $(this).html();
    alert(index + "----" + info);
    });

    $("ul").delegate( "li", "click",function(){
    var index = $(this).index(); //索引位置
    var info = $(this).html();
    alert(index + "----" + info);
    });

  • 相关阅读:
    Java 实现 蓝桥杯 生兔子问题
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    深入探究VC —— 资源编译器rc.exe(3)
    深入探究VC —— 编译器cl.exe(2)
    深入探究VC —— 编译器cl.exe(1)
  • 原文地址:https://www.cnblogs.com/baoshuyan66/p/9971251.html
Copyright © 2011-2022 走看看