jQuery选择器在数组循环中使用变量

时间:2011-11-25 16:06:00

标签: jquery titanium

我的代码出现了问题:

for (var i =0; i < filterArray.length; i++)
{

    name1 = filterArray[i];
    selectstring = 'a[cat="'+name1+'"]';
    filterMenuItem.addItem(name1 , function() {$(selectstring).show(); alert(selectstring)});


}

filterArray目前包含2个项目。“Foo”&amp; “BAR” ..

现在这个“addItem(name1”工作得很好。我们得到一个名为Foo的附加菜单项,另一个名为Bar

问题在于下一部分(函数)。

F&amp;条形图菜单项功能最终做同样的事情。 (例如,他们都获得了选择字符串'a [cat =“bar”]'...正如使用警报测试的那样)

现在我假设发生了这种情况,因为choosetring变量是通过引用函数传递的?那么当我第二次设置choosetring值时,它会覆盖第一个循环的值吗?

如何将选择字符串的唯一副本传递给选择器?我试过“function(chosentring){....}”,但这没有帮助..

感谢任何能够阐明这个问题的人!

编辑:修改后的代码..仍然是同一个问题:

for (var i =0; i < filterArray.length; i++)
{

    var name1 = filterArray[i];
    var selectstring = 'a[cat="'+name1+'"]';

    filterMenuItem.addItem(name1 , function() {alert(selectstring); $('.sortablelist').hide();  $(selectstring).show();});


}

3 个答案:

答案 0 :(得分:1)

它与函数“传递引用”无关 - 实际上没有任何东西传递给函数。

我认为问题在于变量范围。 你没有在var之前在赋值行上使用selectstring,所以假设它是一个全局变量。匿名函数将保留对这个全局变量的引用,在函数运行时将具有'bar'的值。 如果使用var selectstring = (...),将在每次迭代时创建一个单独的闭包,它应该可以工作。

修改

我回答得太快了,答案是错误的,所以这是一个更新的解决方案。我假设在声明匿名函数时正在创建一个闭包,但事实并非如此。因此,实际的解决方案是创建一个闭包来保留每个循环迭代的变量值:

for (var i=0; i < filterArray.length; i++) {
    addFilteredMenuItem(filterArray[i]);
}

function addFilteredMenuItem(itemName) {
    var selectstring = 'a[cat="'+itemName+'"]';
    filterMenuItem.addItem(itemName, function() {
       alert(selectstring);
    });
}

Working example on jsfiddle

我在下面发表评论的解决方案也有效,并且基于相同的原则,但我认为这涉及不必要的自动执行功能看起来很糟糕。

另见this SO thread讨论同一主题。

答案 1 :(得分:1)

你的for循环只有一个闭包,因此将始终使用choosetring的'latest'值。你需要开始一个新的闭包,如下所示:

for (var i =0; i < filterArray.length; i++)
{
  name1 = filterArray[i];
  selectstring = 'a[cat="'+name1+'"]';
  filterMenuItem.addItem(name1, 
    (
     function(selectstring) 
     { 
       return function() {$(selectstring).show(); alert(selectstring) }
     }
    )(selectstring)
  );
}

当choosetring的正确值仍然存在时,函数立即被调用,并且外部函数(因此是其局部变量的新副本)为返回的内部函数创建一个新的闭包。

jQuery .each()函数在你的情况下也可以使用起来相当简单:

$.each(this.filterArray, function(i, filter) {
    filterMenuItem.addItem(name1 , function() {$('a[cat="'+filter+'"]').show(); alert('a[cat="'+filter+'"]')});
});

答案 2 :(得分:0)

我不知道我是否知道你需要什么,但请尝试:

for (var i =0; i < filterArray.length; i++)
{

    name1 = filterArray[i];
    selectstring = 'a[cat="'+name1+'"]';
    filterMenuItem.addItem(name1 , function(selectstring) {$(selectstring).show(); alert(selectstring)});

}