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 相关文章推荐
精通Javascript系列之Javascript基础篇
Jun 07 Javascript
jquery parent和parents的区别分析
Oct 02 Javascript
JavaScript中用于生成随机数的Math.random()方法
Jun 15 Javascript
bootstrap基本配置_动力节点Java学院整理
Jul 14 Javascript
angular4 如何在全局设置路由跳转动画的方法
Aug 30 Javascript
浅谈node中的cluster集群
Jun 02 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
Aug 20 Javascript
js 实现watch监听数据变化的代码
Oct 13 Javascript
Vue程序化的事件监听器(实例方案详解)
Jan 07 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 Javascript
vue prop传值类型检验方式
Jul 30 Javascript
原生js实现自定义难度的扫雷游戏
Jan 22 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利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
php创建图像具体步骤
2017/03/13 PHP
phpstudy的php版本自由修改的方法
2017/10/18 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
php判断IP地址是否在多个IP段内
2020/08/18 PHP
一个用javascript写的select支持上下键、首字母筛选以及回车取值的功能
2009/09/09 Javascript
IE6下js通过css隐藏select的一个bug
2010/08/16 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
javascript框架设计之浏览器的嗅探和特征侦测
2015/06/23 Javascript
Vue.js第四天学习笔记
2016/12/02 Javascript
AngularJS Controller作用域
2017/01/09 Javascript
vue实现表格增删改查效果的实例代码
2017/07/18 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
vue中v-for加载本地静态图片方法
2018/03/03 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
p5.js实现简单货车运动动画
2019/10/23 Javascript
Python实现曲线点抽稀算法的示例
2017/10/12 Python
Python实现识别手写数字 简易图片存储管理系统
2018/01/29 Python
在Pycharm中自动添加时间日期作者等信息的方法
2019/01/16 Python
libreoffice python 操作word及excel文档的方法
2019/07/04 Python
python 定时器每天就执行一次的实现代码
2019/08/14 Python
python3的UnicodeDecodeError解决方法
2019/12/20 Python
python matplotlib imshow热图坐标替换/映射实例
2020/03/14 Python
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
国际花店:Pickup Flowers
2020/04/10 全球购物
项目专员岗位职责
2013/12/04 职场文书
低碳环保标语
2014/06/12 职场文书
开展读书活动总结
2014/06/30 职场文书
新店开张活动方案
2014/08/24 职场文书
支教个人总结
2015/03/04 职场文书
会计简历自我评价
2015/03/10 职场文书
推普标语口号大全
2015/12/26 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书