首先看看点击不同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. 分析轮子(七)- RandomAccess.java

    1:还是先上一个类的继承关系比较图吧! 2:看一下 RandomAccess.java 的源码,空空如也,什么都没有,那她有什么用处呢? /** * Marker interface used by ...

  2. springboot整合三 共享session,集成springsession

    官网介绍 - spring:session:https://docs.spring.io/spring-session/docs/current/reference/html5/ 1. Mave依赖 ...

  3. WebSocket 理论知识整理

    最近工作用到websocket, 之前虽然也用到了一些简单的东西,但是并没有认真整理一下.所以这次准备了解一下WebSocket. WebSocket产生的背景 WebSocket是一种在单个TCP连 ...

  4. Atitit 最近资料文章列表r9 r8 月份 attilax总结

    Atitit 最近资料文章列表r9  r8 月份   attilax总结 atitit tag标签标示规范 attilax总结 v2 r922.docx 2017-09-28 02:04 阅读(27) ...

  5. vue2.0 技巧汇总

    /** * Created by */ export default { trim: (str) => { //删除左右两端的空格 return str.replace(/(^\s*)|(\s* ...

  6. linux shell命令之wc/split及特殊字符

    [时间:2018-07] [状态:Open] [关键词:linux, wc, split, 通配符,转义符,linux命令] 0 引言 整理这篇文章的目的不是为了什么学习,仅仅是为了强化下记忆,以便下 ...

  7. 流媒体之HLS——综述(二)

    [时间:2018-03] [状态:Open] [关键词:流媒体,stream,HLS] 本文是上一篇的后续部分,链接如下:HLS协议综述 2 playlist(m3u8)介绍 HLS中的playlis ...

  8. ORACLE拼日期

    Oracle数据库拼字符串是用"||"连接的.在开发中,经常会用到时间范围的查询 例如  startTime >='2017-05-22 00:00:00' and endT ...

  9. Efficient Online Segmentation for Sparse 3D Laser Scans-- 在线的稀疏点云分割

    在基于激光的自动驾驶或者移动机器人的应用中,在移动场景中提取单个对象的能力是十分重要的.因为这样的系统需要在动态的感知环境中感知到周围发生变化或者移动的对象,在感知系统中,将图像或者点云数据预处理成单 ...

  10. 新内容转入github

    所有新内容已经转入 https://github.com/honggzb/Study-General https://github.com/honggzb/Study2016