0

这个网站和其他地方已经存在几个相关的问题,但似乎没有一个答案适用于我的情况。我有一堆 HTML 中的单选按钮。

<input type="radio" name="b1" value="aa"> aa<br>
<input type="radio" name="b1" value="ab"> ab<br>
<input type="radio" name="b1" value="ac"> ac<br>

<input type="radio" name="b2" value="ba"> ba<br>
<input type="radio" name="b2" value="bb"> bb<br>
<input type="radio" name="b2" value="bc"> bc<br>

<script type="text/javascript">
var PK = {    
   modes: ["b1", "b2"],

   init: function() {        
      // attach actions to radio buttons
      for (var key in this.modes) {
          var mode = this.modes[key];
          $("input[name='" + mode + "']").bind(
               "change", 
               function() { 
                 PK[mode]($("input[name='" + mode + "']:checked").val()); 
               } 
          );
       }
    },

    b1: function(val) { .. do something .. },

    b2: function(val) { .. do something else .. },
};

$(document).ready(function() {
   PK.init();
});
</script>

以上根本行不通。我尝试过 .live 而不是 .bind,即使这样也无法按预期工作。事实上,它们都将动作绑定到模式中的最后一个条目,在上面的“b2”中。也就是说,无论我更改 b1 还是 b2 按钮中的值,都会触发函数 PK.b2()。如果我反转模式条目,则最后一个将采用该值。我怎样才能成功地完成他上面的任务?

4

4 回答 4

3

JavaScript 闭包使用父函数作用域,所以PK[mode]总是引用最后一个mode. 你可以这样做来避免它:

$("input[name=" + mode + "]").bind(
    "change", 
    function(mode) { 
        return function() {
             PK[mode]($("input[name='" + mode + "']:checked").val());
        };
    }(mode)
);

有关更多详细信息,请参见本文的臭名昭著的循环问题部分。

于 2009-10-03T19:05:02.493 回答
2

在代码的 for 循环中,每次都会为不同的模式设置变量模式。但是它只会保留循环的最后一个值。因此,您需要对绑定中的函数进行一些更改。

$("input[name=" + mode + "]").bind(
    "change", 
    function(e) {
        PK[$(this).attr('name')]($(this).val()); 
    } 
);

现在我们使用 jquery 来确定我们正在使用的项目的名称,而不是依赖于一个只有循环中最后一位数据的变量。

于 2009-10-03T18:58:31.337 回答
0

就我所见,有两个问题。

首先,正如lrudor 指出的那样mode闭包中是最后一个迭代的模式。

其次,使用[name=whatever]代替[name="whatever"].

于 2009-10-03T19:13:14.963 回答
0

如果这是您想要做的,我理解您是否正确?

init: function() {
    // attach actions to radio buttons
    for (var key in this.modes) {
        var mode = this.modes[key];
        $("input[name='" + mode + "']")
            .bind("change", function(e) {
                var radio = e.srcElement;
                PK[radio.name](radio.value);
            })
            .bind("click", function() {
                // Loose focus of the radio button once clicked,
                // so the change-event fires
                this.blur();
            });
    }
},
于 2009-10-03T19:52:34.440 回答