在前端群里看见过很多人问过这个问题,今晚又有人问了这个问题,所以写篇文章整理一下。首先看一下代码,点击li之后弹出当前li所对应的索引值。于是很多人刷刷刷写出了下面的代码。

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

但是结果不尽人意,为了简单,我们约定一下页面中有2个li。点击li之后弹出的都是2。

我们首先来分析一下为什么结果是1.我们可以简单的将循环分成两部。

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

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

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

var aLi = document.getElementsByTagName('li');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)i = 2时,不满足条件跳出循环.

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

转载于:https://blog.51cto.com/f2emrwu/1731520

js常见问题之为什么点击弹出的i总是最后一个相关推荐

  1. js源生实现图片点击弹出放大效果

    参考https://blog.csdn.net/qq_36375934/article/details/78952485 的弹出框查看大图,同时总结自己遇到的问题,做个笔记 HTML代码 <!D ...

  2. JS 点击弹出图片/ 仿QQ商城点击左右滚动幻灯片/ 相册模块,点击弹出图片,并左右滚动幻灯片...

    1, 点击弹出图片 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  3. JS特效教程:给网站添加鼠标点击弹出指定汉字特效

    网站添加鼠标点击弹出指定汉字特效,就是鼠标点击站点任何位置,都会随机弹出我们指定的一组汉字中的一个.比如指定"文明,自由,民主,公正,和谐"等,点击鼠标时就会随机显示这一组的某个词 ...

  4. 微信小程序点击弹出输入框

    微信小程序点击弹出输入框 第一次写博客,我决定不要太old school. let's get it!最近在学习微信开发,刚接触到微信小程序,自己尝试着做了一个简单的小程序,过程中发现类似web开发中 ...

  5. layer 上传图片点击取消仍在加载_layer 点击弹出图片

    今天做东西有一个功能:在列表点击图片弹出并放大显示,使用到了layer的页面层,下边是个小demo success:function (e) { var url = e.qrcode_url; //a ...

  6. 2.使用OpenLayers6(ol6)加载Mapbox的TileJSON格式地图实现点击弹出经纬度信息

    文末有源代码下载地址 2.1使用OpenLayers6加载Mapbox的TileJSON格式地图 首先写一下Tile格式和TileJSON格式的区别,Tiles 是传统的瓦片地图服务,Tiles 服务 ...

  7. Js+DVML:很酷实用的右键弹出菜单

    <HTML xmlns:v><HEAD> <head> <meta http-equiv="Content-Type" content=& ...

  8. 点击弹出窗口外任意地方关闭弹出窗口

    问:如何在点击弹出窗口外其他地方时关闭弹出窗口? 答:使用FlexMouseEvent'sMOUSE_DOWN_OUTSIDE事件.用户点击弹出窗口的外部时,会分发此事件.只需要在popUpWindo ...

  9. 基于jQuery鼠标点击弹出登陆框效果

    基于jQuery鼠标点击弹出登陆框效果.这是一款扁平样式风格的jQuery弹出层登陆框特效.效果图如下: 在线预览    源码下载 实现的代码. html代码: <input type=&quo ...

最新文章

  1. hdu 5751 Eades
  2. Java 线程同步 synchronized
  3. php xxtea加密,PHP实现的XXTEA加密解密算法示例
  4. python基础教程是什么语言-终于懂得python中文入门教程
  5. c++构造函数以及类中变量初始化顺序
  6. 有限状态机HDL模板
  7. python十:字典(dict)
  8. 基于python的FFT演示程序
  9. MATLAB绘制正弦波、方波、三角波、锯齿波的mif文件
  10. ML.NET Cookbook:(17)如何在分类数据上训练模型?
  11. integer 转int类型 java_Java数据类型中String、Integer、int相互间的转换
  12. VMware for mac inside error solutions
  13. 计算机网络的结构之Internet结构
  14. java 判断session失效_session过期时间设置和判断session是否过期
  15. 计算机报名照片无法显示,有关人事考试照片审核处理工具的问题
  16. 仙人掌 圆方树 || 静态 + 动态 (差动态)
  17. 拼团商城是如何盈利的?
  18. 电视剧《猎毒人》观后感
  19. STM32 嵌入式学习入门(4)——PWM原理
  20. 基于Arduino通过并联L298N实现四驱麦克纳姆轮巡迹小车

热门文章

  1. java报错 pom.xml第一行报org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project......
  2. Linux系统资源监控--linux命令、nmon和spotlight
  3. mysql数据库优化的几种方法
  4. SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
  5. 改变NumericStepper控件上下箭头的外观.
  6. mysql 分库分表 ~ 柔性事务
  7. 离职后才搞懂vue项目开发流程中的疑惑点
  8. 系统调用的实现(与errno的设置)
  9. UWA DAY 2018 精彩议题全曝光!
  10. TokuDB在生产环境的应用场景(zabbix也可以)