js闭包引起的事件注册问题介绍


Posted in Javascript onMarch 29, 2016

背景:闲暇时间看了几篇关于js作用域链与闭包的文章,偶然又看到了之前遇到的一个问题,就是在for循环中为dom节点注册事件驱动,具体见下面代码:

<!DOCTYPE html>
<html>
  <head>
    <title>js闭包</title>
    <meta charset="utf-8" />
  </head>
  <body>
    <button id="anchor1">1</button>
    <button id="anchor2">2</button>
    <button id="anchor3">3</button>
    <script type="text/javascript" src="jquery-1.12.1.js"></script>
    <script type="text/javascript">
      function pageLoad(){
        for (var i = 1; i <=3; i++) { 
          var anchor = document.getElementById("anchor" + i);
          anchor.onclick = function () {
            console.log("anchor"+i);
          } 
        } 
      } 
      window.onload = pageLoad; 
    </script>
  </body>
</html>

按照正常的想法,结果应该是点击3个按钮分别提示“anchor1”、“anchor2”、“anchor3”;期初我也是这么认为的,但是结果却是不管点击哪个按钮,都会提示“anchor4”。

这是为什么呢?不要着急,待我们慢慢分析,这里面包含js作用域链与闭包的知识,在这里我就不详细介绍了。

首先我们看这个anchor.onclick,这是什么?这是dom0级事件处理程序啊,废话,我也知道,博主是蛇精病吗*************不要吵了,我想说的是这个anchor.onclick

是一个事件处理程序的声明,就像var name="小明"一样,这是声明了,但是还没有执行,这就是关键,我们将上面的js代码修改一下再来看看:

function pageLoad(){
     for (var i = 1; i <=3; i++) { 
       var anchor = document.getElementById("anchor" + i);
         anchor.onclick = function () {
            console.log("anchor"+i);
         } 
         if(i==2){
           debugger;//我们在这里debugger一下,然后在控制台手动触发#anchor1和#anchor2的点击事件
         }
     } 
 } 
 window.onload = pageLoad;

js闭包引起的事件注册问题介绍

看到了吧,我们通过debugger让循环在i==2时停止,然后又去控制台手动触发#anchor1和#anchor2的点击事件,结果控制台打印“anchor2”。

整个的逻辑大致是这样的:anchor.onclick一直保存着i的引用,i在循环中是一直变化的,从i=1到i=4;虽然在循环的过程中,anchor.onclick曾经保存过(注意“曾经”两字),

1,2,3这三种情况,但是i最终变成了4,所以说,无论点击哪个按钮,都会输出“anchor4”

结语:js中作用域链与闭包的知识很重要,虽然在此没有讲,其实是害怕讲不明白,反而误导了大家

以上这篇js闭包引起的事件注册问题介绍就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
非html5实现js版弹球游戏示例代码
Sep 22 Javascript
jQuery封装的获取Url中的Get参数示例
Nov 26 Javascript
javascript中字符串拼接详解
Sep 26 Javascript
jQuery实现响应浏览器缩放大小并改变背景颜色
Oct 31 Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 Javascript
在Node.js应用中使用Redis的方法简介
Jun 24 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
Jun 29 Javascript
理解JS事件循环
Jan 07 Javascript
详解堆的javascript实现方法
Nov 29 Javascript
vue计算属性computed、事件、监听器watch的使用讲解
Jan 21 Javascript
浅谈vuex为什么不建议在action中修改state
Feb 02 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
May 10 Javascript
使用postMesssage()实现跨域iframe页面间的信息传递方法
Mar 29 #Javascript
js滚动条平滑移动示例代码
Mar 29 #Javascript
JavaScript头像上传插件源码分享
Mar 29 #Javascript
js解决movebox移动问题
Mar 29 #Javascript
javascript中不易分清的slice,splice和split三个函数
Mar 29 #Javascript
分析js闭包引起的事件注册问题
Mar 29 #Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
Mar 29 #Javascript
You might like
php zlib压缩和解压缩swf文件的代码
2008/12/30 PHP
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
解析PHP实现下载文件的两种方法
2013/07/05 PHP
php顺序查找和二分查找示例
2014/03/27 PHP
thinkPHP5.0框架引入Traits功能实例分析
2017/03/18 PHP
JavaScript触发器详解
2007/03/10 Javascript
拖动布局之保存布局页面cookies篇
2010/10/29 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
2014/05/07 Javascript
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
javascript实现window.print()去除页眉页脚
2014/12/30 Javascript
JavaScript表格常用操作方法汇总
2015/04/15 Javascript
Webpack 实现 Node.js 代码热替换
2015/10/22 Javascript
jQuery配合coin-slider插件制作幻灯片效果的流程解析
2016/05/13 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
vue实现文章内容过长点击阅读全文功能的实例
2017/12/28 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
微信小程序实现跑马灯效果
2020/10/21 Javascript
详解如何运行vue项目
2019/04/15 Javascript
jQuery AJAX应用实例总结
2020/05/19 jQuery
Python pass 语句使用示例
2014/03/11 Python
Python使用random.shuffle()打乱列表顺序的方法
2018/11/08 Python
python自定义线程池控制线程数量的示例
2019/02/22 Python
python 寻找离散序列极值点的方法
2019/07/10 Python
PyQT5 emit 和 connect的用法详解
2019/12/13 Python
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
美国休闲服装品牌:J.Crew Factory
2017/03/04 全球购物
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
检察官就职演讲稿
2014/01/13 职场文书
教师节商场活动方案
2014/02/13 职场文书
毕业典礼主持词大全
2014/03/26 职场文书
医药销售自我评价200字
2014/09/11 职场文书
离婚协议书范本2014
2014/10/27 职场文书
小学五一劳动节活动总结
2015/02/09 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL
python字符串的多行输出的实例详解
2021/06/08 Python