摘转自:http://www.cnblogs.com/rubylouvre/archive/2009/07/24/1530074.html
要求:让这三个节点的Onclick事件都能正确的弹出相应的参数。
<ul> <li id="a1">aa</li> <li id="a2">aa</li> <li id="a3">aa</li> </ul>
问题:
<script type="text/javascript"> for(var i=1; i < 4; i++){ var id = document.getElementById("a" + i); id.onclick = function(){ alert(i);//现在都是返回4 } } </script>
onclick的绑定函数 function(){alert(i)}的作用域为对应li对象,它里面alert的i的作用域为window,每次循环都是在重写window.i的值,因此循环完,i已是4,点击哪一个li元素都是4
解决方法1:利用闭包(closure)
var lists = document.getElementsByTagName("li"); for(var i=0,l=lists.length; i < l; i++){ lists[i].onclick = (function(i){//保存于外部函函数 return function(){ alert(i); } })(i); }
或
var lists = document.getElementsByTagName("li"); for(var i=0,l=lists.length; i < l; i++){ lists[i].onclick = new function(){ var t = i; return function(){ alert(t+1) } } }
解决方法2:利用事件代理
var ul = document.getElementsByTagName("ul")[0]; ul.onclick = function(){ var e = arguments[0] || window.event, target = e.srcElement ? e.srcElement : e.target; if(target.nodeName.toLowerCase() == "li"){ alert(target.id.slice(-1)) } }
解决方法3:将暂时变量保留于元素节点上。
var lists = document.getElementsByTagName("li"); for(var i=0,t=0,el; el = list[i++];){ el.i = t++ el.onclick = function(){ alert(this.i) } }
解决方法4:使用with语句造成的对象闭包。
var els = document.getElementsByTagName("li") for(var i=0,n=els.length;i<n;i++){ with ({i:i}) els[i].onclick = function() { alert(this.innerHTML+i) }; }
解决方法5:使用try...catch语句构造的异常闭包
var lists = document.getElementsByTagName("li"); for(var i=0,l=lists.length; i < l; i++){ try{ throw i; }catch(i){ lists[i].onclick = function(){ alert(i) } } }
评价:牛人就是牛人,我打死也想不到这么多的方法