代码之家  ›  专栏  ›  技术社区  ›  punkish

jquery:动态地将事件绑定到DOM对象

  •  0
  • punkish  · 技术社区  · 15 年前

    这个网站和其他地方已经存在几个相关的问题,但这些答案似乎都不适用于我的情况。我有一堆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>
    

    这根本不起作用。我试过了。活而不是绑定,即使这样也不能按预期工作。事实上,它们都将操作绑定到模式中的最后一个条目,在上面的“b2”中。也就是说,无论我更改b1或b2按钮中的值,函数pk.b2()都会被激发。如果我反转模式条目,最后一个条目将接受该值。我怎样才能成功地完成上面的任务?

    4 回复  |  直到 15 年前
        1
  •  3
  •   LukáÅ¡ Lalinský    15 年前

    JavaScript闭包使用父函数范围,因此 PK[mode] 总是指最后一个 mode . 你可以这样做来避免它:

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

    例如,请参见 臭名昭著的循环问题 部分 of this article 了解更多详细信息。

        2
  •  2
  •   lrudor    15 年前

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

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

    现在,我们使用jquery来计算我们正在处理的项的名称,而不是依赖一个变量,该变量只包含来自循环的最后一位数据。

        3
  •  0
  •   Community CDub    8 年前

    我所看到的有两个问题。

    首先,作为 lrudor pointed out , mode 在闭包中是最后一个迭代的模式。

    第二,使用 [name=whatever] 而不是 [name="whatever"] .

        4
  •  0
  •   Kristoffer Deinoff    15 年前

    如果这是你想做的,我理解你是正确的吗?

    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();
                });
        }
    },