<ul>
<li>男</li>
<li>女</li>
<li>老</li>
<li>少</li>
</ul>

使用js为多个未知数量的li循环添加事件的时候很容易想到如下代码

for( var i= 0,lis = document.getElementsByTagName("li"),len=lis.length; i<len;i++){
lis[i].onclick = function(){
alert(i);
}
}

但是每次点击都会执行最后一次的结果 alert弹出4

因为在for循环里面指定给lis[i].onclick的事件处理程序,也就是onclick那个匿名函数是在for循环执行完成后(用户单击链接时)才被调用的。而调用时,需要对变量i求值,解析程序首先会在事件处理程序内部查找,但i没有定义。然后,又到方法外部去查找,此时有定义,但i的值是4(只有i大于4才会停止执行for循环)。因此,就会取得该值——这正是闭包(匿名函数)要使用其外部作用域中变量的结果。而且,这也是由于匿名函数本身无法传递参数(故而无法维护自己的作用域)造成的。

那现在原因是知道了,如何来避免这种情况呢?

既然已经知道函数调用外部变量的时候就构成了一个闭包,里面的变量会受到别的地方的影响,那么我们

现在要做的就是,构建一个只有自己本身才可访问的闭包,保存只供本身使用的变量

构建一个闭包很简单,代码如下:

for( var i= 0,lis = document.getElementsByTagName("li"),len=lis.length; i<len;i++){
(function(i){
lis[i].onclick = function() {
alert(i);
}
})(i);
}

JS给元素循环添加事件的问题的更多相关文章

  1. JS闭包机制实现为DOM元素循环添加事件

    HTML代码: <button type='button' class='btn' id='1'>按钮1</button> <button type='button' c ...

  2. 【特效】给元素循环添加class

    经常会遇到给元素循环添加class的效果,例如下面这个图 每个模块的背景色和图标都不相同,但是呢,模块的数量又不确定,说不定有几十个,那我不能设计几十个图标吧,所以,可以做成每9个一循环,也就是第10 ...

  3. js循环添加事件的问题

    1.需求 给下面每个按钮增加事件 <ul id="list"> <li>按钮1</li> <li>按钮2</li> &l ...

  4. 如何在通过knockout数据绑定的DOM元素上添加事件

    通过knockout数据绑定的DOM元素,通过chrome控制台打断点知道,DOM元素会被暂时隐藏,使用document.querySelector()是获取不到的,会显示null,直到数据绑定完成才 ...

  5. js阻止元素的默认事件与冒泡事件

    嵌套的div元素,如果父级和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,从而带来一定的影响. 1. event.preventDefault();  -- 阻止元素的默认 ...

  6. 从循环添加事件谈起对JS闭包的理解

    1.引子 相信很多初学js的人,都遇到这样一种情况:想要给一堆按钮添加各自的事件,比如点击第i个按钮时,弹出i这个值.理所当然地,我们会这样写: var buttons = document.getE ...

  7. js循环添加事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. js中关于动态添加事件,不能使用循环变量的问题

    在编写事件的时候,我们难免会遇到以下这种情况:<!DOCTYPE html><html lang="en"><head> <meta ch ...

  9. dom元素循环绑定事件的技巧

    以前总觉得自己写的代码不太规范,尤其是写原生的时候.举个例子: 要为页面上所有".a"的元素绑定事件,当然了用jquery很方便:$('.a').bind("click& ...

随机推荐

  1. 飘逸的python - 解决一个有限制的组合需求

    假设有一个团队技能的需求. 这类技能是要集齐所有指定的人就能激活. 但是因为同一个人又2种身份存在,比如杨戬/神杨戬,于是便产生了组合. 这种组合跟普通组合不一样,普通组合可以随意组合.而这种组合是每 ...

  2. StaggeredGridView+universal-image-loader载入网路图片实现瀑布流

    StaggeredGridView 开源lib  https://github.com/maurycyw/StaggeredGridView 文章demo下载地址  http://download.c ...

  3. Hacker(九)----黑客攻防前准备1

    黑客在入侵Internet中其他电脑之前,需要做一系列准备工作,包括在电脑中安装虚拟机.准备常用的工具软件及掌握常用的攻击方法. 一.在计算机中搭建虚拟环境 无论时攻击还是训练,黑客都不会拿实体计算机 ...

  4. Android 加速Gradle构建项目

    1. 升级gradle 进入项目文件夹$project/gradle/wrapper/gradle-wrapper.properties, 使用最新的gradle. 修改替换为最新的 distribu ...

  5. ios 面试题 0

    1.__block和__weak修饰符的区别:  1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型.  2.__weak只能在ARC模式下使用,也只能修饰 ...

  6. Mysql 建表时,日期时间类型选择

    mysql(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示  D ...

  7. CentOS 6.4 下安装 Apache

    下载地址:http://mirror.bit.edu.cn/ 参数 描述 prefix 安装目录 enable-rewrite 开启 rewrite 模块 sysconfdir 配置文件目录 ./co ...

  8. RHEL 7.0 修改防火墙配置

    RHEL 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. 关闭firewall: systemctl stop firewalld.service #停止firewal ...

  9. Clojure操作mysql

    在Eclipse中新建一个Clojure工程clj01 clojure 操作mysql需要依赖mysql-connector-java.clojure-contrib与java.jdbc三个jar包. ...

  10. 《Programming WPF》翻译 目录

    原文:<Programming WPF>翻译 目录 注:第1.2章我只做了笔记,没有翻译,请大家阅读时注意. 还有就是,这本书的英文版本下载:[O'Reilly] Programming ...