2010-06-13 94 views
0

我想讓每個數字都顯示爲可點擊。 「1」 應alert() 80, 「2」 應該產生60等MooTools/JavaScript可變範圍

然而,當alert(adjust)被調用時,它僅示出了0,而不是正確的數字。但是,如果註釋掉alert(adjust)未註釋,它會在頁面加載時生成正確的數字,但不會在單擊時生成。

我想知道爲什麼addEvents內的代碼無法訪問先前定義的變量adjust

<html> 
<head> 
<script type="text/javascript" charset="utf-8" src="mootools.js"></script> 
<script type="text/javascript" charset="utf-8"> 
    window.addEvent('domready', function() { 

      var id_numbers = [1,2,3,4,5]; 

      for(var i = 0; i<id_numbers.length; i++) { 
       var adjust = (20 * (5 - id_numbers[i])); 
       // alert(adjust); 
       $('i_' + id_numbers[i]).addEvents({ 
        'click': function() { 
         alert(adjust); 
        } 
       }); 
      } 

    }); 
</script> 
</head> 
<body> 

<div id="i_1">1</div> 
<div id="i_2">2</div> 
<div id="i_3">3</div> 
<div id="i_4">4</div> 
<div id="i_5">5</div> 

</body> 
</html> 

謝謝。

+0

這是一個常見的問題 - 請參閱相關的問題和答案http://stackoverflow.com/questions/tagged/javascript +瓶蓋+循環。 – Anurag 2010-06-13 02:33:50

回答

3

您在for循環中有a very common closure problem

變量封閉在一個封閉共享同一個單一的環境中,因此受到click回調被調用時,該for循環就會自生自滅,而adjust變量將指向左側的最後的值就被分配。

你可以用更倒閉解決這個問題,使用函數工廠:

function makeClickHandler(adjust) { 
    return function() { 
     alert(adjust); 
    }; 
} 

// ... 

for(var i = 0; i<id_numbers.length; i++) { 
    var adjust = (20 * (5 - id_numbers[i])); 

    $('i_' + id_numbers[i]).addEvents({ 
     'click': makeClickHandler(adjust) 
    }); 
} 

這可以說是相當棘手的話題,如果你不熟悉閉包是如何工作的。您可以檢查出以下Mozilla的文章作一簡要介紹: