2010-05-19 52 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