jQuery,关联数组和绑定事件

时间:2012-01-31 14:16:27

标签: javascript jquery loops closures

我想将同一事件绑定到3个复选框,但每次都使用不同的目标:

  var checkboxes = {
    'selector1' : 'target1',
    'selector2' : 'target2',
    'selector3' : 'target3',
  };

  for (selector in checkboxes) {
    var target = checkboxes[selector];

    if (jQuery(selector).is(':checked')) {
      jQuery(target).show();
    }
    else {
      jQuery(target).hide();
    }

    jQuery(selector).bind('change', function() {
      if ($(this).is(':checked')) {
        jQuery(target).show();
      }
      else {
        jQuery(target).hide();
      }
    });
  };

但它不起作用:在“改变”时,3个选择器显示/隐藏第3个目标。

3 个答案:

答案 0 :(得分:3)

这是因为事件处理程序中的代码将使用变量target,而不是创建事件处理程序时的变量值。当事件处理程序运行时,该变量将包含循环中使用的最后一个值。

使用匿名函数创建一个闭包,捕获变量的值:

for (selector in checkboxes) {
  var target = checkboxes[selector];

  if (jQuery(selector).is(':checked')) {
    jQuery(target).show();
  } else {
    jQuery(target).hide();
  }

  (function(target){

    jQuery(selector).bind('change', function() {
      if ($(this).is(':checked')) {
        jQuery(target).show();
      } else {
        jQuery(target).hide();
      }
    });

  })(target);

};

附注:您可以使用toggle方法使代码更简单:

for (selector in checkboxes) {
  var target = checkboxes[selector];

  jQuery(target).toggle(jQuery(selector).is(':checked'));

  (function(target){

    jQuery(selector).bind('change', function() {
      jQuery(target).toggle($(this).is(':checked'));
    });

  })(target);

};

答案 1 :(得分:2)

它不起作用,因为target没有作用于函数内部。块不提供javascript范围。

但是我已经为你减少了它,希望这会有效:

$.each(checkboxes, function(selector, target) {
   $(selector).change(function () {
       $(target).toggle($(selector).is(':checked'));
   }).trigger('change');
});

答案 2 :(得分:0)

target范围是问题!

您可以使用更简单的代码:

  • 使用数据处理程序
  • 使用.toggle(condition)

    $.each(checkboxes, function(selector, target) {
        $(selector).on('change', {target:target}, function (evt) {
            $(evt.data.target).toggle($(this).is(':checked'));
        }).change();
    });