通常我們會這樣給元素添加事件:
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); } }
但結果往往不是我們想象的那樣,它們全部彈出是“我的index是2”,原因是JavaScript是單線程執行任務的,添加事件會被羅列到任務單中,所以i的值全是2;
解決方法:
方式1. 使用閉包。 var ul = document.getElementsByTagName("ul")[0]; var list = ul.getElementsByTagName("li");
function foo(){ for(var i = 0, len = list.length; i < len; i++){ var that = list[i]; list[i].onclick = (function(k){ return function(){ alert("我的index是"+k);
}; })(i); } } foo();
方式2.事件代理 var ul = document.querySelector('ul'); var list = document.querySelectorAll('ul li'); ul.addEventListener('click', function(){ var e = arguments[0] || window.event; var target = e.target || e.srcElement; for(var i = 0, len = list.length; i < len; i++){ if(list[i] == target){ alert("我的index是"+i);
} } });
方式3. 引入jQuery,使用其中的on或delegate進行事件綁定(它們都有事件代理的特性) // delegate方法 $("ul").delegate("li", "click", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); }); // on方法 $("ul").on("click", "li", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); });
方式4. 使用ES6中的新特性let來聲明變量用let來聲明的變量將具有塊級作用域,很明顯可以達到要求,不過需要注意的是得加個'use strict'(使用嚴格模式)才會生效。 var ul = document.getElementsByTagName("ul")[0]; var list = ul.getElementsByTagName("li"); function foo(){'use strict' for(let i = 0, len = list.length; i < len; i++){ list[i].onclick = function(){ alert(i + "----" + this.innerHTML); } } } foo();
僅供參考,如有錯誤請指正!