首先看看点击不同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);
});

js之常见问题--for循环中为什么点击总是弹出最后一个i的更多相关文章

  1. ASP.NET MVC中如何在当前页面上弹出另外一个页面

    注意:不是链接到另一个页面,而是弹出一个页面,当前的页面和弹出页面都存在于浏览器的同一个标签页中,效果如图: 弹出的窗体置于四大天王页面之上,但是无法继续操作底层的页面,代码如下: function ...

  2. (原)android的alertdialog中加入edittext但是不弹出软键盘等问题的解决与原因

    摘要:alertdialog中加入edittext但是不弹出软键盘等问题网上有很多不管用的解决方案, 本文意在给出更有效的解决办法,并初步探究其原因 正文 在对话框中插入文本框是十分常见的需求 通常我 ...

  3. 禁止手机页面中A标签长按弹出路径框

    //禁止手机页面中A标签长按弹出路径框    window.onload=function(){        document.documentElement.style.webkitTouchCa ...

  4. EBS OAF开发中实现參数式弹出窗体

    EBS OAF开发中实现參数式弹出窗体 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 概览 參数式弹出窗体和嵌入式弹出窗体不一样,它拥有独立 ...

  5. 设置电脑中的某个程序不弹出UAC用户控制提示的方法

    有用户发现在电脑开机后总是会弹出UAC用户账户控制窗口,这是因为电脑中的某个程序设置了开机启动,这样就会在开机后启动该程序时出现UAC提示.如果想要省略该提示,可以在电脑中设置该程序不弹出UAC用户控 ...

  6. 用js刷剑指offer(栈的压入、弹出序列)

    题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...

  7. javascript 中的console.log和弹出窗口alert

    主要是方便你调式javascript用的.你可以看到你在页面中输出的内容. 相比alert他的优点是: 他能看到结构话的东西,如果是alert,淡出一个对象就是[object object],但是co ...

  8. 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)

    相信使用Windows Server2008的朋友都遇到过这种情况,用IE打开网站时会弹出“Internet Explorer增强安全配置正在阻止来自下列网站的此应用程序中的内容”的对话框.如下图所示 ...

  9. [js开源组件开发]js手机端浮层控件,并有多种弹出小提示,兼容pc端浏览器

    js dialog组件,包含alert和confirm的实现 本组件所有的资源均在github上可以查看源代码 GitHub 本dialog的组件的例子请在这里查看 demo dialog js di ...

随机推荐

  1. 发现2017年最好的CSS框架

    如今,无数的框架出现在定期而少数人喜欢自助,Foundation和angular.js主宰了整个世界的发展.CSS代表用于描述HTML(或XML)文档表示的样式表语言.一个框架被定义为一个包,它由一组 ...

  2. 使用日志服务进行Kubernetes日志采集

    阿里云容器服务Kubernetes集群集成了日志服务(SLS),您可在创建集群时启用日志服务,快速采集Kubernetes 集群的容器日志,包括容器的标准输出以及容器内的文本文件. 新建 Kubern ...

  3. 记一次免费让网站启用HTTPS的过程

    写在前面 个人网站运行将近2个月了,期间根据酷壳的一篇教程如何免费的让网站启用HTTPS做了一次,中间遇到问题就放下了.昨天孙三苗问我网站地址说要添加友链,出于好奇想看他网站长什么样,顺道也加一下友链 ...

  4. MVC Json方法里的一个坑

    MVC Controller类下面有这样一个方法 // // Summary: // Creates a System.Web.Mvc.JsonResult object that serialize ...

  5. 理解JAVA的IO

    1. 什么是流Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序列 ...

  6. mysql出现unblock with 'mysqladmin flush-hosts'

    朋友发来消息,说一个系统应用登录的时候提示连接超时,让帮忙处理一下.问他应用和数据库是否都正常,回复说数据库好像没有问题,但是应用日志报无法连接数据库. 数据库版本是:5.5.53 让他telnet数 ...

  7. Mybatis抛出:Cannot obtain primary key information from the database, generated objects may be incomplete

    使用 mybatis generator 生成pojo.dao.mapper时,可能会遇到 Cannot obtain primary key information from the databas ...

  8. BizTalk RosettaNet 开发笔记

    RNIF BAM Tracking Error  解决办法:  503: Service Unavailable   解决办法:IIS 应用程序池运行账户用户名或密码错误,用户名不能是doma ...

  9. 查看安装的react-native和react版本

    转:http://blog.csdn.net/miss_ok/article/details/52777115 npm info React-native(目前是0.34.1) 知道最新版本后,通过以 ...

  10. linux的挂载的问题,重启后就挂载就没有了

    我用fdisk命令,分一个/dev/sda6出来,然后用mkfs格式化为ext3,然后挂载到根目录下的PPP文件夹中,挂载是成功了,但是用reboot和shutdown重启或关机后挂载就没有了 要修改 ...