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 相关文章推荐
多浏览器支持的右下角浮动窗口
Apr 01 Javascript
js取滚动条的尺寸的函数代码
Nov 30 Javascript
jQuery实现列表自动循环滚动鼠标悬停时停止滚动
Sep 06 Javascript
使用非html5实现js板连连看游戏示例代码
Sep 22 Javascript
ParseInt函数参数设置介绍
Jan 02 Javascript
javascript中style.left和offsetLeft的用法说明
Mar 07 Javascript
JavaScript希尔排序、快速排序、归并排序算法
May 08 Javascript
JavaScript如何实现跨域请求
Aug 05 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
Dec 08 Javascript
详解JavaScript中this的指向问题
Jan 20 Javascript
Vue服务器渲染Nuxt学习笔记
Jan 31 Javascript
vue.js系列中的vue-fontawesome使用
Feb 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
自动跳转中英文页面
2006/10/09 PHP
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
使用PHP导出Redis数据到另一个Redis中的代码
2014/03/12 PHP
mac os快速切换多个PHP版本的方法
2017/03/07 PHP
JQuery 构建客户/服务分离的链接模型中Table分页代码效率初探
2010/01/22 Javascript
Jquery树插件zTree用法入门教程
2015/02/17 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
Vue制作Todo List网页
2017/04/26 Javascript
js编写选项卡效果
2017/05/23 Javascript
Vue实现按钮旋转和移动位置的实例代码
2018/08/09 Javascript
防止Layui form表单重复提交的实现方法
2019/09/10 Javascript
JavaScript Window浏览器对象模型原理解析
2020/05/30 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
Django框架中数据的连锁查询和限制返回数据的方法
2015/07/17 Python
python 专题九 Mysql数据库编程基础知识
2017/03/16 Python
Python中标准库OS的常用方法总结大全
2017/07/19 Python
Python使用min、max函数查找二维数据矩阵中最小、最大值的方法
2018/05/15 Python
python版DDOS攻击脚本
2019/06/12 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
python多线程分块读取文件
2019/08/29 Python
python 实现多维数组(array)排序
2020/02/28 Python
宝塔面板成功部署Django项目流程(图文)
2020/06/22 Python
英国领先的珍珠首饰品牌:Orchira
2016/09/11 全球购物
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
学习雷锋月活动总结
2014/07/03 职场文书
绿色环保家庭事迹材料
2014/08/31 职场文书
英语导游词
2015/02/13 职场文书
2015年社区工作总结
2015/04/08 职场文书
小区环境卫生倡议书
2015/04/29 职场文书
高一作文之乐趣
2019/11/21 职场文书
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB
解决WINDOWS电脑开机后桌面没有任何图标
2022/04/09 数码科技
JavaScript声明变量和数据类型的转换
2022/04/12 Javascript