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 相关文章推荐
jquery JSON的解析方式
Jul 25 Javascript
读jQuery之二(两种扩展)
Jun 11 Javascript
使用js获取图片原始尺寸
Dec 03 Javascript
完善的jquery处理机制
Feb 21 Javascript
ThinkJS中如何使用MongoDB的CURD操作
Dec 13 Javascript
JS实现的找零张数最小问题示例
Nov 28 Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 Javascript
vue 中swiper的使用教程
May 22 Javascript
从零开始用electron手撸一个截屏工具的示例代码
Oct 10 Javascript
vscode 开发Vue项目的方法步骤
Nov 25 Javascript
详解js加减乘除精确计算
Mar 19 Javascript
Vue页面切换和a链接的本质区别详解
Nov 12 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中接口与抽象类的区别
2013/06/08 PHP
php操作xml
2013/10/27 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
PHP格式化显示时间date()函数代码
2018/10/03 PHP
PHP的mysqli_stmt_init()函数讲解
2019/01/24 PHP
Yii框架安装简明教程
2020/05/15 PHP
Docker 安装 PHP并与Nginx的部署实例讲解
2021/02/27 PHP
Ext.MessageBox工具类简介
2009/12/10 Javascript
基于Jquery实现键盘按键监听
2014/05/11 Javascript
JavaScript判断textarea值是否为空并给出相应提示
2014/09/04 Javascript
nodejs入门教程二:创建一个简单应用示例
2017/04/24 NodeJs
利用JS hash制作单页Web应用的方法详解
2017/10/10 Javascript
vue中使用iview自定义验证关键词输入框问题及解决方法
2018/03/26 Javascript
jQuery UI实现动画效果代码分享
2018/08/19 jQuery
解决JS表单验证只有第一个IF起作用的问题
2018/12/04 Javascript
微信小程序实现文字跑马灯
2020/05/26 Javascript
Vue防止白屏添加首屏动画的实例
2019/10/31 Javascript
nodejs实现UDP组播示例方法
2019/11/04 NodeJs
Vue项目中数据的深度监听或对象属性的监听实例
2020/07/17 Javascript
[01:20]DOTA2上海特级锦标赛现场采访:谁的ID最受青睐
2016/03/25 DOTA
对Python 除法负数取商的取整方式详解
2018/12/12 Python
numpy基础教程之np.linalg
2019/02/12 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
python代码能做成软件吗
2020/07/24 Python
C语言50道问题
2014/10/23 面试题
文秘专业毕业生就业推荐信
2013/11/08 职场文书
接受捐赠答谢词
2014/01/27 职场文书
九年级科学教学反思
2014/01/29 职场文书
产假请假条
2014/04/10 职场文书
四风查摆问题自查报告
2014/10/10 职场文书
2014年局领导班子自身建设情况汇报
2014/11/21 职场文书
2014年幼儿园班级工作总结
2014/12/17 职场文书
2015年业务工作总结范文
2015/04/10 职场文书
卖车协议书范文
2016/03/23 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python