js循环绑定事件

在js中,用循环来为一对元素队列的元素绑定事件,是一个常见的问题。

通常进入误区的新人,都会这么写代码: (假设元素队列为o,默认使用jQuery)

//error method
var o =$(‘.blockHead‘);
for(var i=0; i<o.length; i++){
	o[i].onclick = function(){
		function(i){
		    alert(i);
		}
	}
}

当然这种情况下,你会发现每个元素点击运行时,显示的 i值 都是 o.length-1;

因为js的函数是调用时触发,绑定事件的时候i值并没有被传入执行函数里。

作为异步监听的事件,点击事件发生的时候,循环已经结束,此时的 i值 为[o.length-1], 触发事件传递的参数自然是同一个最大值,而不是预期不同元素传不同值。

解决办法思路:将绑定事件过程中得到的i值,在执行函数域里保存起来;调用时自然就得到相应的结果。

方法一: 使用闭包函数存储i值

var o = $(‘.blockHead‘);
for(var i=0; i<o.length; i++){
	o[i].onclick = (function closure(ii){
               //var ii;
               //we save ii in this scope
		return function(){
			alert(ii);
		}
	})(i);
}

 如上,colsure是一个闭包函数(closure函数名可省去,作匿名闭包函数),声明后立即执行,传递了i值,于是在它的函数域里保存了i值(arguments参数列表里);

函数的返回结果是事件处理函数,其参数ii就是colsure里保存的ii值,也就是循环时就传递的i值。

ps:方法一是非常常见的处理该问题的解决方法;在寻找解决方案的过程里,我发现了另一个写法,如下。

方法二: 将事件绑定的代码写在一个外围函数里 

var o = $(‘.blockHead‘);
for(var i=0; i<o.length; i++){
	attach(i,o[i]);
	function attach(ii,o){
		o.onclick = function(){
			alert(ii);
		};
	}
}

//或者 直接在声明函数后立刻执行
var o = $(‘.blockHead‘);
for(var i=0; i<o.length; i++){
	(function attach(ii,o){
		o.onclick = function(){
			alert(ii);
		};
	})(i,o[i]);
}

  同样的道理,在attach的函数域里,onclick事件得到的ii值已经是执行循环便获取的的i,而外部的i执行完循环后的结果是什么已经跟内部没有关系了。

稍许比方法一麻烦的是,参数需要多传递一个元素的引用。

js循环绑定事件

时间: 2024-10-13 16:14:21

js循环绑定事件的相关文章

遇到的问题(JS循环绑定事件)

问题描述:想通过循环的方式给HTML元素绑定事件,结果失败---总是会只能绑定到最后一个元素. HTML <div id="bnts"> <span></span> <span></span> <span></span> <span></span> </div> JS var bnts = document.getElementById("bnts"

js循环绑定事件解决方案

var add_the_handlers = function (nodes) { var helper= function (i) {return function (e) {alert(i);};}; var i; for (i = 0; i < nodes.length; i += 1) { nodes[i].onclick =helper(i); }};

JavaScript利用闭包循环绑定事件

我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用. 1.首先我们举一个简单的例子. html部分: <a href="#">首页</a> <a href="#">作品</a> <a href="#">文章</a> <a href="#">工具</a> <

JS中绑定事件顺序(事件冒泡与事件捕获区别)

在JS中,绑定的事件默认的执行时间是在冒泡阶段执行,而非在捕获阶段(重要),这也是为什么当父类和子类都绑定了某个事件,会先调用子类绑定的事件,后调用父类的事件.直接看下面实例 <!Doctype html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> *{margin:0;p

JS循环添加事件

通常我们会这样给元素添加事件: var ul=document.getElementsByTagName("ul")[0]; var list=document.getElementsByTagName("li"); for(var i=0;i<li.length;i++){ list[i].onclick=function(){ alert("我的index是"+i); } } 但结果往往不是我们想象的那样,它们全部弹出是"我的

JS(绑定事件)

事件绑定方式一:属性中绑定 <input type="button" value="+" onclick="fun1()"> <script> function fun1(){ alert(123); } </script> 事件绑定方式一带参数this,this指代本标签 <div class="div1" onclick="fun1(this)">div1

js on绑定事件

abort 当用户中断下载图像时触发.activate 当对象设置为活动元素时触发.afterprint 对象所关联的文档打印或打印预览后立即在对象上触发.afterupdate 当成功更新数据源对象中的关联对象后在数据绑定对象上触发.beforeactivate 对象要被设置为当前元素前立即触发.beforecopy 当选中区复制到系统剪贴板之前在源对象触发.beforecut 当选中区从文档中删除之前在源对象触发.beforedeactivate 在 activeElement 从当前对象变

JavaScript利用闭包解决循环绑定事件

例子: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <button></button> <button></button> <button></button> </body> <script type="text/javasc

给html元素循环绑定事件

/** * 添加点击的样式 */ function addClickClass(){ var eles = ["a.province",".citys"]; var classes = ["hover","hover2"]; for (var i = 0; i < eles.length; i++) { var obj = new addClickClass_(i,eles,classes); $(eles[i]).bi