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

0
6

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

1. <!DOCTYPEHTML>

2. <html>

3. <head>

4. <metacharset=”utf-8″/>

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

6. <styletype=”text/css”>

7. p{background:gold;}

8. </style>

9. <scripttype=”text/javascript”>

10.functioninit(){

11.varpAry=document.getElementsByTagName(“p”);

12.for(vari=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. functioninit1(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=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. functioninit2(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

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

5. alert(arguments.callee.i);

6. }).i=i;

7. }

8. }

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

1. functioninit3(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

4. (function(arg){

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

6. alert(arg);

7. };

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

9. }

10.}

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

1. functioninit4(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

4. (function(){

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

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

7. alert(temp);

8. }

9. })();

10.}

11.}

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

1. functioninit5(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

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

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

6. alert(arg);

7. }

8. }(i);

9. }

10.}

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

1. functioninit6(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

4. pAry[i].onclick=newFunction(“alert(“+i+”);”);//new一次就产生一个函数实例

5. }

6. }

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

1. functioninit7(){

2. varpAry=document.getElementsByTagName(“p”);

3. for(vari=0;i<pAry.length;i++){

4. pAry[i].onclick=Function(‘alert(‘+i+’)’);

5. }

6. }

<

发布回复

请输入评论!
请输入你的名字