2010-10-30 31 views
1

我在頁面上有一堆元素,其ID全部存儲在名爲ids []的數組中。將函數分配給事件處理函數後,變量保持不變

我已經初始化了第三方DOM腳本,用於檢測元素何時被拖動的每個div。下一步是爲每個元素的onDrag事件分配一個函數。

爲簡單起見,我只想顯示一個彈出對話框,指出被拖動元素的ID。我通過我的數組迭代如下:

for (i=0;i<ids.length;i++) 
{ 
document.getElementById(ids[i]).onDrag = function(){alert(ids[i])} 
} 

這一切似乎都不錯,但觸發我的任何元素的拖動事件導致一個對話框彈出,指出數組中的最後一個元素的ID。換句話說,它在我的迭代中看起來像上面的函數總是爲我的數組中的最後一個索引進行評估。我覺得我在這裏錯過了一些非常簡單的事情,但這個問題正在讓我瘋狂。

+0

看到這個:http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical例如 – 2010-10-30 23:53:49

回答

4

您所遇到的東西被稱爲關閉和它的Javascript的重要組成部分。

閉合是能夠與結合這些變量(即「封閉」的表述)的環境中具有自由變量一起表達(通常是功能)。

會發生什麼是分配給ondrag的匿名函數關閉它的環境,包括變量i。因此,只要i在此函數之外更改,i就會相應地包含新值。

您可以在當前上下文中解決此問題的方法是使用附加的自我執行功能創建另一個作用域。

for (var i=0; i<ids.length; i++) { 
    document.getElementById(ids[i]).onDrag = (function(i){ // <- i is a parameter 
    return function() { 
     alert(ids[i]); // <- i will be the inner value saved from outside 
    }; 
    })(i); // <- invoke immidiately with the i from outside 
} 

你可以閱讀更多的話題:Use Cases for JavaScript Closures通過@kangax

+0

非常有幫助的解釋....我知道有一個關鍵術語,我失蹤了。現在我知道研究關閉。謝謝! – 2010-10-31 00:11:10

1

執行以下操作的變化,

for (...){ 
    SetOnDrag(ids[i]); 
} 

function SetOnDrag(id) 
{ 
    document.getElementById(id).onDrag = function() { alert(id); }; 
} 
+0

謝謝,這個工作就像一個魅力。 – 2010-10-31 00:10:20

相關問題