2009-10-03 3 views
0

Несколько связанных вопросов уже существуют на этом сайте и в других местах, но ни один из ответов, похоже, не применим к моей ситуации. У меня есть куча переключателей в HTML.jQuery: динамически связывающие события с объектами dom

<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». То есть, функция PK.b2() запускается, изменяю ли значение в кнопках b1 или b2. Если я отменяю записи режимов, последний принимает значение. Как я могу выполнить его выше успешно?

ответ

3

Замки 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

В цикле for в вашем коде переменный режим устанавливается каждый раз для разных режимов. Однако он сохранит только последнее значение цикла. поэтому вместо этого вам нужно внести некоторые изменения в функцию внутри связывания.

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

Теперь мы используем JQuery, чтобы выяснить название пункта мы работаем, а не полагаться на переменную, которая имеет только последний бит данных из цикла.

0

Есть две проблемы из того, что я вижу.

Во-первых, как lrudor pointed out, mode в закрытии - последний режим, повторяющийся.

Во-вторых, используйте [name=whatever] вместо [name="whatever"].

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(); 
      }); 
    } 
}, 
Смежные вопросы