2011-04-04 54 views
11

有人能告訴我我在做什麼錯嗎?我簡化它下面,但我基本上是試圖創建一個列表,並有一個引用只在循環中可用的變量的單擊事件。如何將可變參數傳遞給使用jQuery的匿名函數?

for (var i = 0; i < data.length; i++) {                   
    $newRow = $(rowFormat);      
    $('a:first', $newRow).click(function(i){ 
    return function() { alert(i); } 
    }); 
    $list.append($newRow);  
} 
+0

你做了 「錯誤」 的事情是稱爲封閉。你給每個點擊函數一個refference給同一個變量'i'。 – ITroubs 2011-04-04 15:06:24

+0

@ITROUBS:他清楚地知道這一點,並試圖解決它(事實上,他沒有給任何*他們提及循環中使用的「i」;他將其隱藏在[外部]匿名函數的參數列表)。他只是忘記了一些括號 - 見大衛的答案。 :-) – 2011-04-04 15:16:29

+0

是的,你是對的。沒有正確地讀取代碼;-) – ITroubs 2011-04-04 15:44:03

回答

13

您沒有調用外部函數。

$('a:first', $newRow).click(function(j){ 
    return function() { alert(j); } 
}(i)); /* Pay special attention to this line, it is where the major change is */ 

由於T.J. Crowder提到,你可以將工廠移出循環。

function my_factory(j) { 
    return function() { 
     alert(j); 
    }; 
} 

$('a:first', $newRow).click(my_factory(i)); 
+0

通過在點擊時調用您自己的參數,您將失去傳入的事件參數。 – Eli 2011-04-04 14:58:30

+4

+1 @Mike:建議您移動工廠功能在循環之外,但;你不必要地創建了一堆額外的工廠函數,你只需要一個函數(爲'click'創建各種函數)。也建議查看事件委派,而不是爲每一行創建一個單獨的事件處理程序。 – 2011-04-04 14:59:55

+0

@Eli:這不是代碼的作用。接受'j'的函數不是'click'處理函數,它*構建並返回* click處理函數。 'click'處理函數是調用'alert'的函數。 – 2011-04-04 15:00:28

3

你已經差不多了,只是一個小小的改變。這實際上是我在Javascript中實際使用閉包的最喜歡的例子。

基本上,您需要創建一個接受值的函數,並返回使用該值的函數。請參閱下面的註釋行,瞭解您的示例缺失的內容。你的代碼創建了匿名函數,但沒有調用它。

for (var i = 0; i < data.length; i++) {                   
    $newRow = $(rowFormat); 
    var fn = (function (value) { 
    return function() { 
     alert(value); 
    }; 
    }) (i); //this is what you were missing, you need to invoke the anonymous function 
    $('a:first', $newRow).click(fn); 
    $list.append($newRow);  
} 
0

使用'綁定'附加'click'事件並傳遞一個參數。使用 'event.data',你將能夠得到您的參數的正確的價值:

例1:

$(document).ready(function() 
{ 
    for (var i = 0; i < data.length; i++) 
    {                   
     $newRow = $(rowFormat);      
     $('a:first', $newRow).bind('click', {i: i}, 
      function (event) 
      { 
       alert(event.data.i); 
      } 
     ); 
     $list.append($newRow);  
    } 
}); 

例2:

$(document).ready(function() 
{ 
    $(".selectorA").each(function() 
    { 
     var elementId = $(this).attr("id"); 

     for(var i = 0; i < 20; i++) 
     { 
      $('#question' + i).bind('click', {currentIndex: i, elementId: elementId}, 
       function (event) 
       { 
        alert(event.data.currentIndex + " | " + event.data.elementId); 
       } 
      ); 
     } 
    } 
}); 
相關問題