2010-05-19 51 views
3

我有這樣的情況: 有 DIV塊與像「rateN_wrapper」哪裏是「N」的ID是div的數量:灌裝陣列數字

<div id="rate1_wrapper"> 
    <a href="#" id="0_1">...</a> 
    <a href="#" id="0_2">...</a> 
    <a href="#" id="0_3">...</a> 
</div> 

<div id="rate2_wrapper"> 
    <a href="#" id="1_1">...</a> 
    <a href="#" id="1_2">...</a> 
    <a href="#" id="1_3">...</a> 
</div> 

... 

var ratings = new Array(); 
for (i=0; i < 8; i++) 
{ 
    ratings[i] = -1; // Default is unrated 

} 

for (i=0; i < 8; i++) 
{ 
    $('#rate' + i + '_wrapper a').click(function() { 
     ratings[i] = parseInt($(this).attr('id').split('_')[1]); 
     console.debug(ratings); 
    }); 
} 

我的工作是填寫數組需要放置點擊鏈接的id(解析)。但它總是隻改變數組(8)的最新元素。爲什麼?

回答

2

這是由for循環中的閉包引起的問題。您可以通過解析父ID查找該ID:

for (i=0; i < 8; i++) 
{ 
    $('#rate' + i + '_wrapper a').click(function() { 
    var parentId = $(this).parent('div').attr('id'); 
    var index = /\d/.exec(parentId); 
    ratings[index] = parseInt($(this).attr('id').split('_')[1]); 
    }); 
} 
1

因爲您創建的函數正在關閉i變量。它看到的是對當前值的i的引用,而不是創建函數時的值。在for循環結束後,我將是8,所以你所有的匿名函數都會更新ratings[8]。我想,這可能會解決它:

for (i=0; i < 8; i++) 
{ 
    var idx = i; 
    $('#rate' + idx + '_wrapper a').click(function() { 
     ratings[idx] = parseInt($(this).attr('id').split('_')[1]); 
     console.debug(ratings); 
    }); 
} 

我不知道,如果聲明循環體內的VAR將重新綁定每次迭代。如果是這樣,那麼匿名函數將只能看到idx在創建函數時的值。這是一種方式,我知道將工作:

function CreateHandler(idx) { 
    return function() { 
     ratings[idx] = parseInt($(this).attr('id').split('_')[1]); 
     console.debug(ratings); 
    } 
} 

for (i=0; i < 8; i++) { 
    $('#rate' + idx + '_wrapper a').click(CreateHandler(i)); 
} 

因此,您創建,將創建正確的索引對匿名函數的功能。返回的匿名函數在創建時會看到idx的值。

+0

這也有可能完全被使用jQuery。每(),它可能會更清楚 – 2010-05-19 20:24:14

+0

這並沒有幫助我避免for循環。 – Ockonal 2010-05-19 20:29:54

+0

其實,想想吧,如果你在匿名函數體內聲明var idx = i而不是外部循環體,第一個例子會工作... – 2010-05-19 20:30:02