JS闭包导致循环给按钮添加事件时总是执行最后一个
加入如下脚本代码:
- <script>
- var list_obj = document.getElementsByTagName('li');
- for (var i = 0; i <= list_obj.length; i++) {
- list_obj[i].onclick = function() {
- alert(i);
- }
- }
- </script>
运行后,奇怪的发现无论点击那个li标签,alert出的都是最后一个的内容,5
下面做下分析:因为在for循环里面指定给list_obj[i].onclick的事件处理程序,也就是onclick那个匿名函数是在for循环执行完成后(用户单击链接时)才被调用的。而调用时,需要对变量i求值,解析程序首先会在事件处理程序内部查找,但i没有定义。然后,又到方法外部去查找,此时有定义,但i的值是4(只有i大于4才会停止执行for循环)。因此,就会取得该值——这正是闭包(匿名函数)要使用其外部作用域中变量的结果。而且,这也是由于匿名函数本身无法传递参数(故而无法维护自己的作用域)造成的。
那现在原因是知道了,如何来避免这种情况呢?
既然已经知道函数调用外部变量的时候就构成了一个闭包,里面的变量会受到别的地方的影响,那么我们
现在要做的就是,构建一个只有自己本身才可访问的闭包,保存只供本身使用的变量
构建一个闭包很简单,代码如下:
方式一:
- var list_obj = document.getElementsByTagName('li');
- for (var i = 0; i <= list_obj.length; i++) {
- <span style="white-space:pre"> </span>list_obj[i].onclick = (function(i){ // outer function
- <span style="white-space:pre"> </span>return function(){ //inner function
- <span style="white-space:pre"> </span>alert(i);
- <span style="white-space:pre"> </span>};
- <span style="white-space:pre"> </span>})(i);
- }*
方式二:
- var list_obj = document.getElementsByTagName('li');
- for (var i = 0; i <= list_obj.length; i++) {
- (function(i){
- //var p = i
- list_obj[i].onclick = function() {
- alert(i);
- }
- })(i);
- }
JS闭包导致循环给按钮添加事件时总是执行最后一个的更多相关文章
- js用for循环为对象添加事件并传递参数
var objArr = getObjArr(id); for(var i=0; i<objArr.length; i++){ var param=objArr.param ad ...
- Unity3D的按钮添加事件有三种方式
为Unity3D的按钮添加事件有三种方式,假设我们场景中有一个Canvas对象,Canvas对象中有一个Button对象. 方式一: 创建脚本ClickObject.cs,然后将脚本添加到Canvas ...
- vuejs 添加事件时出现TypeError: n.apply is not a function
vuejs项目中给表单元素添加事件时出现了TypeError: n.apply is not a function的错误,后来发现错误原因时处理事件的函数名和data中定义的变量名相同 当给事件添加处 ...
- GUI编程笔记(java)06:GUI窗体添加按钮并对按钮添加事件案例
1.需求:把按钮添加到窗体,并对按钮添加一个点击事件. 步骤: (1)创建窗体对象(2)创建按钮对象(3)把按钮添加到窗体(4)窗体显示 2.编写程序思路: 窗体布局:窗体中组件的排列方式 布局分类 ...
- js闭包解决多个点击事件
<script> var severalObj=window.document.getElementsByName("button"); for(var i=0;i&l ...
- 【转】为ListView每个Item上面的按钮添加事件
原文网址:http://blog.csdn.net/qq435757399/article/details/8256453 1.先看下效果图: 在这里仅供测试,我把数据都写死了,根据需要 ...
- Js闭包与循环
目标:点击任何一个li,提示当前点击位置 <ul> <li>第1个</li> <li>第2个</li> <li>第3个</ ...
- js闭包for循环总是只执行最后一个值得解决方法
<style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...
- 一百、SAP中ALV事件之十三,给ALV的自定义按钮添加事件
一.我们查看定义的按钮,有一个名字是ZADD的自定义按钮 二.代码如下,用于判断点击了哪个按钮 三.点击测试按钮之后,会弹出一个弹窗 完美
随机推荐
- html中a标签做容器的问题
今天试验了一下a标签当作容器的问题,若a包含的容器中没有a标签的话,a标签是可以被当作成容器使用的,在谷歌浏览器这种浏览器中是可行的,但是在低版本的IE中会有bug出现,就是浏览器在解析的时候会把a标 ...
- Canvas 属性,方法
context . restore() //弹出堆最上面保存的绘图状态 context . save() //在绘图状态堆上保存当前绘图状态 绘图状态可以看作当前画面应用的所有样式和变形的一个快照 ...
- chrome 优秀的插件推荐
就本人使用过的chrome插件推荐下: 1:Adblock Plus 免费的广告拦截器,可阻止所有烦人的广告及恶意软件和跟踪. 2:ChaZD 英文翻译,妈妈再也不用担心我英文看不懂了,ChaZD 查 ...
- Ubuntu Linux上安装oracle jdk
说明:由于很多系统不支持使用OpenJDK,因此在ubuntu下会需要安装Oracle JDK.而Oracle JDK的安装貌似没有提供apt方式,因此安装Oracle JDK的方式相对麻烦一些,我经 ...
- URAL 2080 莫队
题意 有m种卡 给出卡的使用序列 要求每次从卡堆的顶部抽一张出来 刚好符合序列 输出初始 卡堆的排序 再输出每次抽出卡用后 卡插回卡堆的时候 这张卡上面有几张卡 初始排序很容易就可以搞出来 但是需要注 ...
- 类似网易新闻 title栏 滚动时 文字放大&变色
http://files.cnblogs.com/files/n1ckyxu/ScrollTitleView.zip
- which go
http://www.yiibai.com/go/go_environment.html
- JDBC 基本操作
1. 简介 JDBC(Java DataBase Connectivity) 是有一些接口和类构成的API JDBC是J2SE的一部分, 又java.sql: javax.sql包组成. 应用程序 ...
- 【译】使用UIKit进行面向对象的编程
在WWDC 2015上,Apple谈了Swift中面向协议编程的话题,令人深思.在那之后,好像每个人都在讨论关于协议扩展的话题,这个新的语言特性使每个人都有所困惑. 我阅读了许多关于Swift中协议的 ...
- oracle创建、删除账户
1.创建 /*第1步:创建表空间 */create tablespace xybi datafile 'E:\oracle\oradata\zzxe\xybi_d01' size 100M ; /*第 ...