问题:每次弹出for循环的最后一个值,而不是点击每个p就弹出对应的值?
<p>1</p> <p>2</p> <p>3</p> <script> window.onload = function () { var ps=document.getElementsByTagName('p'); for(var i=0; i<ps.length; i++){ ps[i].onclick=function(){ alert(i); } } } </script>出现问题原因:js事件处理器在线程空闲事件不会运行,导致最后运行的时候输出的都是i最后的值。
解决办法:使用闭包将变量i的值保护起来
// 法1:加一层闭包,i以函数参数形势传递给内层函数 window.onload = function () { var ps=document.getElementsByTagName('p'); for(var i=0; i<ps.length; i++){ (function(arg){ ps[i].onclick=function(){ alert(arg); } })(i); } } // 法2:加一层闭包,i以局部变量形势传递给内层函数 window.onload = function () { var ps=document.getElementsByTagName('p'); for(var i=0; i<ps.length; i++){ (function(){ var temp=i; ps[i].onclick=function(){ alert(temp); } })(); } } // 法3:加一层闭包,返回一个函数作为响应事件 window.onload = function () { var ps = document.getElementsByTagName('p'); for (var i = 0; i < ps.length; i++) { ps[i].onclick = function (arg) { return function(){ alert(arg); } }(i); } } // 法4:将变量i保存给在每个段落对象p上 window.onload = function () { var ps = document.getElementsByTagName('p'); for (var i = 0; i < ps.length; i++) { ps[i].i=i; ps[i].onclick = function () { alert(this.i); } } } // 法5:将变量i保存在匿名函数自身 window.onload = function () { var ps = document.getElementsByTagName('p'); for (var i = 0; i < ps.length; i++) { (ps[i].onclick = function () { alert(arguments.callee.i); }).i=i; } } // 法6:用Function实现,实际上每产生一个函数实例就会产生一个闭包 window.onload = function () { var ps = document.getElementsByTagName('p'); for (var i = 0; i < ps.length; i++) { ps[i].onclick = new Function ("alert("+i+");"); //new一次就产生一个函数实例 } } // 法7:用Function实现 window.onload = function () { var ps = document.getElementsByTagName('p'); for (var i = 0; i < ps.length; i++) { ps[i].onclick = Function ("alert("+i+");"); } }