首先看這段代碼:
<button id="0">0</button> <button id="1">1</button> <button id="2">2</button> <script> $(function(){ for (var i=0; i<=2; i++) { $("#" + i).on("click", function() { alert(i); }); }; }) </script>
這段代碼如果不仔細看的話會誤以為三個按鈕點擊結果分別為0,1,2。但是運行結果卻是3,3,3。
我們來分析一下代碼執行過程:前三遍循環分別給按鈕0,1,2綁定了alert(i)的事件,第四遍循環開始時i=3,不符合i<=2的條件,因此終止循環。這里要注意的是,前三遍循環綁定的是alert(i)事件,而不是alert(0),alert(1),alert(2),因為在綁定的過程中on的事件處理函數里的代碼並沒有運行,因此在觸發click事件之前並不知道i等於幾,代碼此時只認為i是一個全局變量(實際上i的作用域為最外層的function)。上面分析了,當循環結束時i等於3,因此3個按鈕點擊均為alert(3)。
但是在實際工作中我們經常會遇到這種循環綁定事件的需求,那該怎么辦呢?以下是我總結的幾個常用的方法。
1. 數據通過jquery的event.data與事件綁定
for (var i=0; i<=2; i++) { $("#" + i).on("click", {key: i}, function(event) { alert(event.data.key); }); };
2. 數據通過jquery的data方法與dom元素綁定
for (var i=0; i<=2; i++) { $("#" + i).data("key", i); $("#" + i).on("click", function(){ alert($(this).data("key")); }); };
3. 第三種方法是原生js的方法,在on函數的外層寫一個立即執行的函數,其目的是生成作用域,循環三遍即生成三個作用域,i的值由最下面的參數傳入,三個作用域互不影響,因此也可以實現循環綁定的效果
for (var i=0; i<=2; i++) { (function(i) { $("#" + i).on("click", function(){ alert(i); }); })(i); };
如果大家有更簡便的方法,歡迎一起交流~