JS閉包導致迴圈給按鈕新增事件時總是執行最後一個
阿新 • • 發佈:2019-01-23
今天再做需求時有一個功能是這樣的,就是有不定個的按鈕,且點選按鈕時都需要執行一個方法(引數不一樣)
那麼我很自然的就想到了,迴圈給每個按鈕新增事件和引數就好了,由於不方便上傳系統程式碼,下面以一個簡單例子來說明.
<pre name="code" class="html"><html> <body> <ul id="list"> <li>按鈕1</li> <li>按鈕2</li> <li>按鈕3</li> <li>按鈕4</li> <li>按鈕5</li> </ul> </body> </html>
比如現在要實現這麼一個功能,在頁面上點選上面的按鈕1到按鈕5時分別alert出1,2,3,4,5.
那麼很多人自然想到如下這麼做:
加入如下指令碼程式碼:
<script>
var list_obj = document.getElementsByTagName('li');
for (var i = 0; i <= list_obj.length; i++) {
list_obj[i].onclick = function() {
alert(i);
}
}
</script>
執行後,奇怪的發現無論點選那個li標籤,alert出的都是最後一個的內容,5
下面做下分析:因為在for迴圈裡面指定給list_obj[i]
那現在原因是知道了,如何來避免這種情況呢?
既然已經知道函式呼叫外部變數的時候就構成了一個閉包,裡面的變數會受到別的地方的影響,那麼我們
現在要做的就是,構建一個只有自己本身才可訪問的閉包,儲存只供本身使用的變數
構建一個閉包很簡單,程式碼如下:
方式一:
var list_obj = document.getElementsByTagName('li');
for (var i = 0; i <= list_obj.length; i++) {
<span style="white-space:pre"> </span>list_obj[i].onclick = (function(i){ // outer function
<span style="white-space:pre"> </span>return function(){ //inner function
<span style="white-space:pre"> </span>alert(i);
<span style="white-space:pre"> </span>};
<span style="white-space:pre"> </span>})(i);
}*
方式二:
var list_obj = document.getElementsByTagName('li');
for (var i = 0; i <= list_obj.length; i++) {
(function(i){
//var p = i
list_obj[i].onclick = function() {
alert(i);
}
})(i);
}
現在再執行就能得到我們想要的效果了。