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 动态table添加colspan\rowspan 参数的方法
Jul 25 Javascript
使用PHP+JQuery+Ajax分页的实现
Apr 23 Javascript
javascript常用功能汇总
Jul 05 Javascript
AngularJS在IE8的不支持的解决方法
May 13 Javascript
如何实现星星评价(jquery.raty.js插件)
Dec 21 Javascript
JavaScript实现图片切换效果
Aug 12 Javascript
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
Nov 28 Javascript
利用vue开发一个所谓的数独方法实例
Dec 21 Javascript
jquery实现动态添加附件功能
Oct 23 jQuery
解决vue.js提交数组时出现数组下标的问题
Nov 05 Javascript
js实现无限层级树形数据结构(创新算法)
Feb 27 Javascript
vue npm install 安装某个指定的版本操作
Aug 11 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
PHP中如何实现常用邮箱的基本判断
2014/01/07 PHP
PHP-Java-Bridge使用笔记
2014/09/22 PHP
php中heredoc与nowdoc介绍
2014/12/25 PHP
php实现网页缓存的工具类分享
2015/07/14 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
2015/08/21 PHP
php+ajax实现无刷新分页
2015/11/18 PHP
php表单习惯用的正则表达式
2017/10/11 PHP
Laravel框架控制器,视图及模型操作图文详解
2019/12/04 PHP
Firefox window.close()的使用注意事项
2009/04/11 Javascript
jQuery.prototype.init选择器构造函数源码思路分析
2013/02/05 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
jQuery处理xml格式的返回数据(实例解析)
2013/11/28 Javascript
node.js中的events.emitter.removeListener方法使用说明
2014/12/10 Javascript
简单介绍JavaScript数据类型之隐式类型转换
2015/12/28 Javascript
解决Window10系统下Node安装报错的问题分析
2016/12/13 Javascript
获取JavaScript异步函数的返回值
2016/12/21 Javascript
html5 canvas 详细使用教程
2017/01/20 Javascript
Bootstrap禁用响应式布局的实现方法
2017/03/09 Javascript
jQuery中图片展示插件highslide.js的简单dom
2018/04/22 jQuery
vue.js将时间戳转化为日期格式的实现代码
2018/06/05 Javascript
JavaScript 判断对象中是否有某属性的常用方法
2018/06/14 Javascript
Vue 简单实现前端权限控制的示例
2020/12/25 Vue.js
js加减乘除精确运算方法实例代码
2021/01/17 Javascript
python3+PyQt5实现使用剪贴板做复制与粘帖示例
2017/01/24 Python
Python实现抓取网页生成Excel文件的方法示例
2017/08/05 Python
Python-numpy实现灰度图像的分块和合并方式
2020/01/09 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
2020/02/20 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
2020/06/02 Python
法国家具及室内配件店:home24
2017/01/21 全球购物
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
什么是数组名
2012/05/10 面试题
如何现实servlet的单线程模式
2014/08/05 面试题
工作失误检讨书范文大全
2014/01/13 职场文书
《彩色世界》教学反思
2014/04/12 职场文书
招商引资工作汇报
2014/10/28 职场文书