欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript的闭包特性如何给循环中的对象添加事件(一)

程序员文章站 2023-10-24 20:07:51
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。原因是初学者并未理解JavaScript的闭包特性。 1. 2. 3. 4. < ......

    初学者经常碰到的,即获取html元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。原因是初学者并未理解javascript的闭包特性。

1. <!doctype html>

2.  <html>

3.  <head>

4.  <meta charset="utf-8" />

5.  <title>闭包演示</title>

6.  <style type="text/css">

7.      p {background:gold;}

8.  </style>

9.  <script type="text/javascript">

10.function init() {

11.    var pary = document.getelementsbytagname("p");

12.    for( var i=0; i<pary.length; i++ ) {

13.         pary[i].onclick = function() {

14.         alert(i);

15.    }

16.  }

17.}

18.</script>

19.</head>

20.<body οnlοad="init();">

21.<p>产品 0</p>

22.<p>产品 1</p>

23.<p>产品 2</p>

24.<p>产品 3</p>

25.<p>产品 4</p>

26.</body>

27.</html>

 

以上场景是初学者经常碰到的。即获取html元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。

原因是初学者并未理解javascript的闭包特性。通过element.οnclick=function(){alert(i);}方式给元 素添加点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。

了解了原因,下面就由几种方式可与解决:

1、将变量 i 保存给在每个段落对象(p)上

1.  function init1() {

2.    var pary = document.getelementsbytagname("p");

3.    for( var i=0; i<pary.length; i++ ) {

4.       pary[i].i = i;

5.       pary[i].onclick = function() {

6.          alert(this.i);

7.       }

8.    }

9.  }

2、将变量 i 保存在匿名函数自身

1.  function init2() {

2.    var pary = document.getelementsbytagname("p");

3.    for( var i=0; i<pary.length; i++ ) {

4.     (pary[i].onclick = function() {

5.          alert(arguments.callee.i);

6.      }).i = i;

7.    }

8.  }

3、加一层闭包,i 以函数参数形式传递给内层函数

1.  function init3() {

2.    var pary = document.getelementsbytagname("p");

3.    for( var i=0; i<pary.length; i++ ) {

4.     (function(arg){

5.         pary[i].onclick = function() {

6.            alert(arg);

7.         };

8.     })(i);//调用时参数

9.    }

10.}

4、加一层闭包,i 以局部变量形式传递给内层函数

1.  function init4() {

2.    var pary = document.getelementsbytagname("p");

3.    for( var i=0; i<pary.length; i++ ) {

4.      (function () {

5.        var temp = i;//调用时局部变量

6.        pary[i].onclick = function() {

7.          alert(temp);

8.        }

9.      })();

10.  }

11.}

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

1.  function init5() {

2.    var pary = document.getelementsbytagname("p");

3.    for( var i=0; i<pary.length; i++ ) {

4.     pary[i].onclick = function(arg) {

5.         return function() {//返回一个函数

6.         alert(arg);

7.       }

8.     }(i);

9.    }

10.}

6、用function实现,实际上每产生一个函数实例就会产生一个闭包

1.  function init6() {

2.      var pary = document.getelementsbytagname("p");

3.      for( var i=0; i<pary.length; i++ ) {

4.        pary[i].onclick = new function("alert(" + i + ");");//new一次就产生一个函数实例

5.      }

6.  }

7、用function实现,注意与6的区别

1.  function init7() {

2.      var pary = document.getelementsbytagname("p");

3.      for( var i=0; i<pary.length; i++ ) {

4.           pary[i].onclick = function('alert('+i+')');

5.      }

6.  }