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 相关文章推荐
JS操作Cookie写入和读取实例代码
Oct 20 Javascript
巧用replace将文字表情替换为图片
Apr 17 Javascript
jQuery 插件开发指南
Nov 14 Javascript
理解javascript定时器中的单线程
Feb 23 Javascript
老生常谈Javascript中的原型和this指针
Oct 09 Javascript
form+iframe解决跨域上传文件的方法
Nov 18 Javascript
jquery实现input框获取焦点的方法
Feb 06 Javascript
ES6新增数据结构WeakSet的用法详解
Aug 07 Javascript
Vue组件库发布到npm详解
Feb 17 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
Sep 25 Javascript
微信小程序 自定义复选框实现代码实例
Sep 04 Javascript
浅谈克隆 JavaScript
Nov 02 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开发文档 会员收费1期
2012/08/14 PHP
浅析php与数据库代码开发规范
2013/08/08 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
javascript使用location.search的示例
2013/11/05 Javascript
浅析Cookie中的Path与domain
2013/12/18 Javascript
jQuery 无限级菜单的简单实例
2014/02/21 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
Visual Studio中js调试的方法图解
2014/06/30 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
Node.js抓取中文网页乱码问题和解决方法
2015/02/10 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
jQuery页面刷新(局部、全部)问题分析
2016/01/09 Javascript
浅谈JavaScript对象的创建方式
2016/06/13 Javascript
完美解决浏览器跨域的几种方法(汇总)
2017/05/08 Javascript
vue中使用element组件时事件想要传递其他参数的问题
2019/09/18 Javascript
基于Angular 8和Bootstrap 4实现动态主题切换的示例代码
2020/02/11 Javascript
原生JavaScript创建不可变对象的方法简单示例
2020/05/07 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
Python最基本的输入输出详解
2015/04/25 Python
浅谈function(函数)中的动态参数
2017/04/30 Python
使用python将多个excel文件合并到同一个文件的方法
2019/07/09 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
2020/07/13 Python
Python map及filter函数使用方法解析
2020/08/06 Python
python使用dlib进行人脸检测和关键点的示例
2020/12/05 Python
html5 学习简单的拾色器
2010/09/03 HTML / CSS
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
中国电视购物:快乐购
2017/02/04 全球购物
印尼美容产品购物网站:PerfectBeauty.id
2017/12/01 全球购物
护理专业自我鉴定
2014/01/30 职场文书
金融学专科生自我鉴定
2014/02/21 职场文书
班级心理活动总结
2014/07/04 职场文书
土建技术员岗位职责
2015/04/11 职场文书
销售开票员岗位职责
2015/04/15 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
python opencv通过4坐标剪裁图片
2021/06/05 Python