`
Tyrion
  • 浏览: 257575 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

javascript中循环添加事件时的闭包问题解决

    博客分类:
  • JS
 
阅读更多

这是一个经典问题,只不过有一段时间不写纯js了,最近老是掉进以前跌过的坑,这次花了半天时间爬出来,所以记录一下。

 

昨天写js代码在给自定义的div注册onclick事件时发现得到的值始终是循环里的最后一个层里的值。

最早的代码:

 

for(var i in array){
	var rowDiv = document.createElement("div");
	rowDiv.innerText = array[i]["name"];
	rowDiv.onclick = function(){//注册点击事件
		pNode = this.parentNode;
		pNode.previousSibling.value = this.innerText;//将当前div的值赋给输入框
		if(onclickCallback){//传入了回调函数则执行回调
			onclickCallback(array[i]);
		}
	};
}

 

为了不干扰阅读的视线,将与这个问题无关的代码直接裁掉:

 

for(var i in array){
	var rowDiv = document.createElement("div");
	rowDiv.innerText =array[i];
	rowDiv.onclick = function(){//注册点击事件
		alert(array[i]);
	};
}

 

这里发现点击一个div之后alert出来的始终是最后一次循环的值。这个现象立马想起来这是一个经典的闭包问题,在执行onclick的事件时会向外部函数寻找array[i]的定义,这里的i在for循环执行完之后变成了array[array.length-1]。

 

网上搜了一下,改进的方法有很多种:

方法1,外层包一个匿名函数,将每次循环的索引结果作为入参传入并自执行:

 

for(var i in array){
	(function(obj){
		var rowDiv = document.createElement("div");
		rowDiv.innerText = obj;
		rowDiv.onclick = function(){//注册点击事件
			alert(obj);
		};
	})(array[i]);
}

 

方法2,同样是利用闭包,给innerText赋值部分并没有问题,有问题的只是用到了闭包特性的onclick事件注册部分,所以就改onclick部分:

 

for(var i in array){
	var rowDiv = document.createElement("div");
	rowDiv.innerText = array[i];
	rowDiv.onclick = (function(obj){//注册点击事件
		return function(){
			alert(obj);
		};
	})(array[i]);
}

 

方法3,以上解决翻案的语法看起来挺晦涩,但都是在闭包里打转,个人觉得能不用闭包的地方就尽量别用,一个不小心就会碰上内存泄漏的问题。下面给出另一种解法:

for(var i in array){
	var rowDiv = document.createElement("div");
	rowDiv.innerText = array[i];
	rowDiv.obj = array[i];
	rowDiv.onclick = function(){//注册点击事件
		alert(this.obj);
	};
}

这是我个人认为较好的方案,给dom对象添加自定义属性来保存值,在div的事件触发时可以通过this来引用。

 

0
3
分享到:
评论

相关推荐

    js实现为a标签添加事件的方法(使用闭包循环)

    主要介绍了js实现为a标签添加事件的方法,基于闭包循环实现事件添加的功能,涉及javascript闭包与事件操作相关技巧,需要的朋友可以参考下

    JavaScript详解(第2版)

    1.4 JavaScript及其在Web页面中的位置 3 1.5 Ajax是什么 5 1.6 JavaScript是什么样子的 6 1.7 JavaScript及其在Web开发中承担的角色 7 1.8 JavaScript和事件 9 1.9 标准化JavaScript和W3C 11 1.9.1 ...

    浅谈JS闭包中的循环绑定处理程序

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

    Javascript闭包演示代码小结

    闭包演示 p {background:gold;} function init() { ...在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。 原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=f

    JavaScript权威指南(第6版)中文文字版

    《JavaScript权威指南(第6版)》要讲述的内容涵盖JavaScript语言本身,以及web浏览器所实现的JavaScript API。本书第6版涵盖了 html5 和 ecmascript 5,很多章节完全重写,增加了当今 web 开发的最佳实践的内容,新增...

    JavaScript权威指南(第6版)

    《JavaScript权威指南(第6版)》主要讲述的内容涵盖JavaScript语言本身,以及Web浏览器所实现的JavaScript API。本书第6版涵盖了HTML5和ECMAScript 5,很多章节完全重写,增加了当今Web开发的最佳实践的内容,新增...

    JavaScript权威指南(第6版)中文版pdf+源代码

     9.3 JavaScript中Java式的类继承207  9.4 类的扩充210  9.5 类和类型212  9.6 JavaScript中的面向对象技术217  9.7 子类230  9.8 ECMAScript 5 中的类239  9.9 模块248  第10章 正则表达式的模式匹配253  ...

    JavaScript权威指南(第6版)(附源码)

    本书要讲述的内容涵盖JavaScript语言本身,以及Web浏览器所实现的JavaScriptAPI。本书第6版涵盖了HTML5和ECMAScript5,很多章节完全重写,增加了当今Web开发的最佳实践的内容,新增的章节包括jQuery、服务器端...

    JavaScript权威指南(第6版)(中文版)

    《JavaScript权威指南(第6版)》主要讲述的内容涵盖JavaScript语言本身,以及Web浏览器所实现的JavaScript API。本书第6版涵盖了HTML5和ECMAScript 5,很多章节完全重写,增加了当今Web开发的最佳实践的内容,新增...

    JavaScript 权威指南(第四版).pdf

     9.3 JavaScript中Java式的类继承207  9.4 类的扩充210  9.5 类和类型212  9.6 JavaScript中的面向对象技术217  9.7 子类230  9.8 ECMAScript 5 中的类239  9.9 模块248  第10章 正则表达式的模式匹配253  ...

    JavaScript权威指南(第六版) 清晰-完整

    OReilly精品图书系列:JavaScript权威指南(第6版) 作者简介  David Flanagan是一名程序员,也是一名作家,它的个人网站是 。他在O’Reilly出版的其他畅销书还包括《JavaScript Pocket Reference》、《The Ruby ...

    Javascript数组操作高级心得整理

    第一章JavaScript基础 1. 如何实现JavaScript 4 (1) 如何把JavaScript代码放到HTML页面里 4  使用[removed]标签,直接在HTML代码里加入JavaScript代码 4  使用[removed]调用外部的JavaScript(.js文件) 4  如何...

    JavaScript权威指南(第6版)

    《JavaScript权威指南(第6版)》要讲述的内容涵盖JavaScript语言本身,以及web浏览器所实现的JavaScript API。本书第6版涵盖了 html5 和 ecmascript 5,很多章节完全重写,增加了当今 web 开发的最佳实践的内容,新增...

    JavaScript权威指南(第6版) 中文版

    《JavaScript权威指南(第6版)》要讲述的内容涵盖JavaScript语言本身,以及web浏览器所实现的JavaScript API。本书第6版涵盖了 html5 和 ecmascript 5,很多章节完全重写,增加了当今 web 开发的最佳实践的内容,新增...

    ActionScript开发技术大全

    26.1.2ActionScript与JavaScript交互 566 26.1.3ActionScript与桌面程序交互 567 26.2网页脚本交互示例 568 26.3桌面应用交互示例 571 26.4小结 573 第27章ActionScript打印控制 574 27.1使用打印作业对象 574 ...

    Node.js MongoDB AngularJSWeb开发中文版.part1

    4.3.2 在回调中实现闭包 64 4.3.3 链式回调 65 4.4 小结 66 4.5 下一章 66 第5章 在Node.js中处理数据I/O 67 5.1 处理JSON 67 5.1.1 把JSON转换成JavaScript对象 67 5.1.2 把JavaScript对象转换为JSON 68 5.2 使用...

    JavaScript高级教程

    第 1 章 JavaScript 是什么...............................................1 3 1.1 历史简述..............................................1 1.2 JavaScript 实现................................................

Global site tag (gtag.js) - Google Analytics