0

我有一個HTML頁面幾種形式(動態創建的),所以我讓他們在JS到一個數組,然後我添加一個EventListener每一個,就像這樣:JS的addEventListener參數

var forms = document.getElementsByTagName('form'); 

for(i=0; i < forms.length; i++) { 
    forms[i].addEventListener('change', function(){ 
     checkAllFilled(i); 
    }); 
} 

所以在功能checkAllFilled我做了一些東西。

的問題是,如果我有7種形式(從forms[0]forms[6]),我在forms[2]工作,它總是叫checkAllFilled(7),而不是調用checkAllFilled(2)。這就像變量i被設置在for循環的最後一個值中。

我該怎麼做?

謝謝!

+0

讓什麼@Utkanos說+你必須聲明你'i'變量。 ('var i = 0') –

回答

2

另一種方式是隻使用從2015年的ECMAScript

for(let i=0; i < forms.length; i++) { 
    forms[i].addEventListener('change', function(){ 
     checkAllFilled(i); 
    }); 
} 
+0

這是一個很棒的解決方案!:)謝謝! – Ommadawn

4

這就像變量「i」被設置在 循環的最後一個值中。

這正是發生了什麼事情。

想一想。您的事件處理程序稍後運行,for循環已經結束並消失。那時,變量具有循環留下的任何值 - 因此,事件總是會報告相同的單個值。

相反,您需要通過閉包綁定迭代值。有幾種方法。一種是通過立即執行的功能(IEF)。

forms[i].addEventListener('change', (function(i) { return function(){ 
    checkAllFilled(i); 
}; })(i)); 

我們將迭代值作爲函數變量傳遞給我們的IEF。這樣,它通過閉包傳遞給處理程序。這是值得reading up on these

+0

感謝您的解釋和參考:)但它不起作用! :( – Ommadawn

+0

IIF需要接受傳遞的參數,這是調用'checkAllFilled'而不是'i'時需要使用的內容。現在讀取此代碼示例,它不會執行與原始代碼不同的任何操作。 –

+0

錯字 - 錯過了'I'作爲IEF參數。已解決和工作。[Fiddle](https://jsfiddle.net/) – Utkanos

1

您總是調用最後生成的事件偵聽器,因爲您先生成這些偵聽器(全部具有相同的名稱),然後調用它們中的最後一個。

這裏最好的解決方案是根據計數器值i爲處理事件的函數指定名稱。

1

使用forEach()代替for循環:

var forms = document.getElementsByTagName('form'); 

[].slice.call(forms).forEach(function(form, i) { 
    form.addEventListener('change', function(){ 
     checkAllFilled(i); 
    }); 
});