1

我有一张消息地图说:

var Mapping = {
"notnow": 2,
"expensive": 3,
"not_worth_it": 4
}

我有一堆 html 元素(让我们说具有相同名称的 div)所以

<div id="notnow"></div>

,ETC

现在我想为每个人附加一个点击处理程序,我运行一个循环,如下所示

function setThemUp(){
   for(var item in Mapping)
   {
      $("#" + item).bind('click', function () {
      Apply(Mapping[item]); });
   }
}

但由于某种原因,它们似乎都被绑定到“not_worth_it”:4。不是他们各自的价值观。

我正在使用 Jquery 1.5。

有人可以解释为什么会发生这种情况吗?

我的猜测是,与其将 Mapping[item] 解析为它们的值,不如将它作为引用或其他东西传递,这就是为什么由于 item 的值最终指向“不值得”,所有它们都使用该值调用函数本身。我可以通过任何方式克服它们。

将它们中的每一个硬编码为

  $("#notnow").bind('click', function () {
      Apply(Mapping["notnow"]); });
  $("#expensive").bind('click', function () {
      Apply(Mapping["expensive"]); });
  $("#not_worth_it").bind('click', function () {
      Apply(Mapping["not_worth_it"]); });

确实有效,但我更喜欢带有循环的优雅解决方案。

回答

我选择了关闭解决方案

function setThemUp(){
   for(var item in Mapping)
   {
       $("#" + item).bind('click', (function () {
            return function(temp) {
                 Apply(Mapping[temp]); };
            })(item));
       }
   }

原因是,这更多是循环不起作用的原因,而不是关于 jquery 的优化,因为这毕竟是一个有代表性的例子,而不是我的实际代码,这是解决这个问题的一个优雅的解决方案。

4

3 回答 3

4

这是范围问题的典型案例:您item在每个绑定的处理程序中引用变量。但是,变量item发生了变化->它被分配了Mapping对象文字的所有属性,最后一个是not_worth_it.

创建闭包可能有助于保留item每个回调的状态:

for(var item in Mapping)
{
   $("#" + item).bind('click', (function(currentItem)
   {//IIFE, pass item as argument---------/
        return function ()
        {//return function, \/ access to closure scope
            Apply(Mapping[currentItem]);
         };
    }(item)););
}

但这似乎有些矫枉过正,为什么不简单地委托事件并使用Mapping[$(this).attr('id')]

于 2012-11-16T18:13:53.403 回答
0

我建议改用这种形式:

将类添加mapped到映射 div。

HTML

<div id="notnow" class="mapped"></div>

JS

function setThemUp(){
    $('.mapped').bind('click', function () {
        Apply(Mapping[this.id]); 
    });
}
于 2012-11-16T18:26:52.510 回答
-1

问题是你需要写:

for (var item in Mapping) 

而不是 foreach。

于 2012-11-16T18:12:57.637 回答