2008-12-11 80 views
9

我有一個類似於這裏的問題:Event handlers inside a Javascript loop - need a closure?但我使用jQuery和給出的解決方案似乎觸發事件時,它的約束,而不是點擊。jQuery閉包,循環和事件

這裏是我的代碼:

for(var i in DisplayGlobals.Indicators) 
{ 
    var div = d.createElement("div"); 
    div.style.width = "100%"; 
    td.appendChild(div); 

    for(var j = 0;j<3;j++) 
    { 
     var test = j; 
     if(DisplayGlobals.Indicators[i][j].length > 0) 
     { 
      var img = d.createElement("img"); 
      jQuery(img).attr({ 
        src : DisplayGlobals.Indicators[i][j], 
        alt : i, 
        className: "IndicatorImage" 
       }).click(
        function(indGroup,indValue){ 
         jQuery(".IndicatorImage").removeClass("active"); 
         _this.Indicator.TrueImage = DisplayGlobals.Indicators[indGroup][indValue]; 
         _this.Indicator.FalseImage = DisplayGlobals.IndicatorsSpecial["BlankSmall"]; 
         jQuery(this).addClass("active"); 
        }(i,j) 
       ); 
       div.appendChild(img); 
      } 
    } 
} 

我已經試過了幾個都沒有成功不同的方式...

原來的問題是,_this.Indicator.TrueImage總是最後的價值,因爲我使用循環計數器而不是參數來選擇正確的圖像。

回答

14

你錯過了一個函數。該功能。點擊需要一個函數作爲參數,所以你需要做的:

.click(
    function(indGroup,indValue) 
    { 
     return function() 
     { 
      jQuery(".IndicatorImage").removeClass("active"); 
      _this.Indicator.TrueImage = DisplayGlobals.Indicators[indGroup][indValue]; 
      _this.Indicator.FalseImage = DisplayGlobals.IndicatorsSpecial["BlankSmall"]; 
      jQuery(this).addClass("active"); 
     } 
    }(i,j); 
); 
+1

謝謝:)頓覺有點傻! – 2008-12-11 14:27:28

13

解決方案通過格雷格仍然是有效的,但你可以不用現在創建附加的封閉,利用的jQuery eventData參數click方法(或bind或任何其他事件綁定方法)。

.click({indGroup: i, indValue : j}, function(event) { 
    alert(event.data.indGroup); 
    alert(event.data.indValue); 
    ... 
}); 

看起來更簡單,可能更有效(每次迭代少一次閉包)。

關於bind方法的文檔有關於事件數據的描述和一些示例。

6

只要您使用jQuery 1.4.3及更高版本,Nikita的答案就可以正常工作。對於在此之前(回1.0)版本中,你將不得不使用bind如下:

.bind('click', {indGroup: i, indValue : j}, function(event) { 
    alert(event.data.indGroup); 
    alert(event.data.indValue); 
    ... 
}); 

希望這有助於其他人仍然在使用1.4.2(像我)