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 相关文章推荐
网页防止tab键的使用快速解决方法
Nov 07 Javascript
使用jquery修改表单的提交地址基本思路
Jun 04 Javascript
ExpressJS入门实例
Jan 14 Javascript
使用JavaScript+canvas实现图片裁剪
Jan 30 Javascript
js实现对table动态添加、删除和更新的方法
Feb 10 Javascript
jquery实现像栅栏一样左右滑出式二级菜单效果代码
Aug 24 Javascript
JS实现灵巧的下拉导航效果代码
Aug 25 Javascript
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
Apr 30 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
Jun 09 Javascript
vue如何在自定义组件中使用v-model
May 14 Javascript
vue.js计算属性computed用法实例分析
Jul 06 Javascript
JS实现处理时间,年月日,星期的公共方法示例
May 31 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
探讨:array2xml和xml2array以及xml与array的互相转化
2013/06/24 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
php生出随机字符串
2017/07/06 PHP
Prototype源码浅析 String部分(一)之有关indexOf优化
2012/01/15 Javascript
JS跨域代码片段
2012/08/30 Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
2013/05/19 Javascript
js中的如何定位固定层的位置
2014/06/15 Javascript
node.js中的console.dir方法使用说明
2014/12/10 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
2015/03/04 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
2016/02/20 Javascript
浅谈addEventListener和attachEvent的区别
2016/07/14 Javascript
详解JS中的快速排序与冒泡
2017/01/10 Javascript
SelectPage v2.4 发布新增纯下拉列表和关闭分页功能
2017/09/07 Javascript
js console.log打印对象时属性缺失的解决方法
2019/05/23 Javascript
JS中的算法与数据结构之队列(Queue)实例详解
2019/08/20 Javascript
JS实现横向跑马灯效果代码
2020/04/20 Javascript
编写v-for循环的技巧汇总
2020/12/01 Javascript
[07:25]DOTA2-DPC中国联赛2月5日Recap集锦
2021/03/11 DOTA
浅谈django三种缓存模式的使用及注意点
2018/09/30 Python
python 搭建简单的http server,可直接post文件的实例
2019/01/03 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
CSS3 中filter(滤镜)属性使用详解
2020/04/07 HTML / CSS
html5-canvas中使用clip抠出一个区域的示例代码
2018/05/25 HTML / CSS
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
英国排名第一的餐具品牌:Denby Pottery
2019/11/01 全球购物
英国豪华家具和家居用品购物网站:Teddy Beau
2020/10/12 全球购物
别名指示符是什么
2012/10/08 面试题
教师的实习自我鉴定
2013/12/17 职场文书
竟聘演讲稿范文
2013/12/31 职场文书
物理系毕业生自荐书范文
2014/02/22 职场文书
机房搬迁方案
2014/05/01 职场文书
新教师培训方案
2014/06/08 职场文书
辞职离别感言
2015/08/04 职场文书
MyBatis自定义SQL拦截器示例详解
2021/10/24 Java/Android
vue项目如何打包之项目打包优化(让打包的js文件变小)
2022/04/30 Vue.js