javascript紧接上一张for循环的问题,我自己的理解

这类问题,通常都是在for循环里,根据i的变化作为dom的下标来作当前dom的点击事件,

预期是,每个点击事件都对应相应的i下标,但是问题是,每次点击的都是最后一次节点的dom。

原因就是其实我们作点击事件的时候,for循环已经执行完毕了。

而且i如果没得到相应的保存,就只会为循环的最后一个值。

做了一共6中方法,大概分为两个范畴,

第一个是设置自定义属性,这个可以包括dom的自定义属性和函数的自定义属性;

第二个是利用闭包空间,来让i保存在闭包空间中的变量中;

上代码

html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<form>
	<input type = "text" value ="1212">
	<input type = "text" value ="1212">
	<input type = "text" value ="1212">
	<input type = "text" value ="1212">
	<input type = "text" value ="1212">
</form>
</body>
</html>

javascript:

<script type="text/javascript">
    var form = document.getElementsByTagName(‘form‘)[0];
    var ipt = form.getElementsByTagName(‘input‘);

    //自定义属性
    for(var i = 0 ; i < ipt.length ;i++){
    	ipt[i].index = i ;
    	ipt[i].onclick = function(){
    		alert(this.index);
    	}
    }
     //下面很多方法都是通过闭包空间来解决的
     //闭包就是内部函数的外部函数被其之外的变量调用时便产生了一个闭包空间
     //闭包空间的变量不会被销毁,直到闭包空间的内部函数全部执行完毕
     //要清楚,闭包空间作为外部函数一定要被调用,才会产生闭包,若外部函数(闭包空间)没被调用,内部函数就不会被调用
    //闭包空间保存
	for(var i = 0 ; i < ipt.length ; i++){
		//以下自我执行函数为闭包空间
		//形参arg保存实参i的值,直到循环结束
        ipt[i].onclick = (function(arg){
        	return function(){
        		alert(arg);
        	}})(i);
	}

    //说到底都是闭包空间保存变量的作用,只要在内部函数外部顶一个函数
    //因为内部函数依赖外部函数的变量(参数),所以如果内部函数没有执行完成,赖以生存的外部函数
    //就不会被js的gc机制销毁,虽然作用链已断

    for(var i = 0 ; i < ipt.length ;i++){
    	//以下为闭包空间
    	//arg保存i
    	//跟前面的方法差不多,都是传参完成,通过形参保存实参
    	function al(arg){
	    	ipt[arg].onclick = function(){
	    		alert(arg);
	    	}
    	}
    	al(i)
    }

    //这种方法和arg传参才不多,只不过讲参数,作为闭包空间的内部参数存在
    //另外其实参数和函数内部的变量差不多的存在
	for(var i = 0 ; i< ipt.length ;i++){
		//以下为闭包空间
		//用temp保存i
		ipt[i].onclick = (function (){
			var temp = i;
			return function(){
				alert(temp)
			}
		})()
	}

	//函数自定义属性
	//通过给每个函数都添加下标,在执行函数的时候,弹窗自己的下面
	//arguments.callee表示当前执行最近的一个函数,用this表示会弹窗undifined
	for(var i = 0 ; i< ipt.length ;i++){
		(ipt[i].onclick = (function (){
				alert(arguments.callee.i)
		})).i = i;//这里声明的是函数的下标
	}

	//又是闭包空间
	//有些眉目了么
	for(var i = 0 ;i < ipt.length ;i++){
	    //以下为闭包空间,一定要记得,闭包空间的函数一定要执行
	    //通过temp来保存i,但是temp又被内部函数调用,所以temp不会马上被销毁
		(function(){
			var temp = i ;
			ipt[i].onclick = function(){
				alert(temp);
			}
		})()
	}
</script>

  

时间: 2024-10-27 08:02:10

javascript紧接上一张for循环的问题,我自己的理解的相关文章

(转)深入理解JavaScript的闭包特性 如何给循环中的对象添加事件

深入理解JavaScript的闭包特性如何给循环中的对象添加事件 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head&g

无废话JavaScript(上)

<程序员>2008.09期有一篇名为<无废话ErLang>的文章,这让我想到了许多的诸如“无废话C”.“无废话书评”这类的文章,也想到了JavaScript可没有一篇“无废话”,所以决定开个篇来写这个.与这个决定相关的,索性,这次就写个最简单的吧. 声明一下:如果只想看复杂的东西,不要读这篇文章了. 一.JavaScript最初其实是过程式的 追溯到1.0时代的JavaScript,其实是过程式的.它的基本特性有只有两项,一项是能够直接放在网页的HTML标签中去接管事件,例如: [

深入理解JavaScript的闭包特性如何给循环中的对象添加事件

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head> 4.  <meta charset="utf

js实现点击按钮实现上一张下一张相册滚动效果

/****判断图片是否构成滚动效果*/$(function(){    if($("#bar").find('img').size()*71<=$("#bar").width()){           $("#table_img").width($("#bar").find('img').size()*71);    }    if($("#bar").find('img').size()*71&g

Javascript 返回上一页

1. Javascript 返回上一页 history.go(-1), 返回两个页面: history.go(-2); 2. history.back(). 3. window.history.forward()返回下一页 4. window.history.go(返回第几页,也可以使用访问过的URL) 例:<a href="javascript:history.go(-1);">向上一页</a> response.Write("<script

javascript 返回上一页并且刷新

返回上一页并且刷新: location.href=document.referrer; document对象的referrer属性,返回导航到当前网页的超链接所在网页的URL. javascript 返回上一页并且刷新

完善ext.grid.panel中的查询功能(紧接上一篇)

今天的代码主要是实现,Ext.grid.panel中的查询,其实我也是一名extjs新手,开始想的实现方式是另外再创建一个新的grid类来存放查询出的数据(就是有几个分类查询就创建几个grid类),这样虽然实现了,但是多写了不少代码,之后网上找到了方法. 代码如下:请结合昨天的代码看,否则你是看不明白的 /*我们操作查询的功能键是放在grid的tabbar中的,下面就是创建的grid的tabbar,其中查询操作就在其中,此代码紧接上一篇文章,这个类上一篇文章中也有,但是没有实现查询功能,红色字体

Chromium on Android: Android系统上Chromium主消息循环的实现分析

摘要:刚一开始接触Chromium on Android时,就很好奇Chromium的主消息循环是怎么整合到Android应用程序中的.对于Android程序来说,一旦启动,主线程就会有一个Java层的消息循环处理用户输入事件等系统事件,而对Chromium来说,它有自己另一套消息循环的实现,这个实现有哪些特点,又将如何无缝整合到Android Java层的消息循环中去,正是本文所要讨论的话题. 原创文章系列,转载请注明原始出处为http://blog.csdn.net/hongbomin/ar

Javascript 返回上一页 返回下一页

1. Javascript 返回上一页 history.go(-1), 返回两个页面: history.go(-2); 2. history.back(). 3. window.history.forward()返回下一页 4. window.history.go(返回第几页,也可以使用访问过的URL) 例:<a href="javascript:history.go(-1);">向上一页</a> response.Write("<script