有没有办法在不使用全局变量的情况下打破jQuery中的事件递归?

时间:2010-10-16 10:38:39

标签: events recursion jquery

我有一个包含2个文本输入和2个跨度控件的表单。通常,当文本框A被更改时,将触发事件以更改范围A,并且当更改文本框B时,将触发事件以更改范围B.

然而,在一个特定的情况下,我想要更改文本框A或文本框B来更新范围A和B.我尝试将事件连接到相应的控件,在这种情况下,但它不起作用,因为那里在事件构建代码中设置了很多状态(更不用说每个事件调用'this',这会使逻辑使用错误的控件,如果它是从一个不同于它的意图中触发的那个)。

为了简单起见,最好在创建时将字符串(表示其他文本输入id)传递给事件处理程序,然后在第二个控件上手动调用change()事件。但是,这会使事物处于递归的无限循环中。我想到了一种绕过递归的方法,但它需要一个全局变量。

有没有比这更好的方法,最好是不需要全局变量的方法?

ml_inEvent = false;



   $ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event) {
        // Other processing happens here...

        if (event.data.controlToFire != '') {
            var $controlToFire = $('#' + event.data.controlToFire);
            if ($controlToFire.length) {
                // Use a global variable to ensure this event is not fired again
                // as a result of calling the other one
                if (!ml_inEvent) {
                    ml_inEvent = true;
                    $controlToFire.change();
                    ml_inEvent = false;
                }
            }
        }
    });

1 个答案:

答案 0 :(得分:3)

您可以使用.trigger()上的extraParameters参数来突破,例如:

$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event, fire) {
  // Other processing happens here...
  if(fire !== false)  $('#' + event.data.controlToFire).trigger('change', false);
});

You can give it a try here。这样做的是事件处理程序回调不仅接收event object,还接收传入的任何其他参数,在这种情况下,我们只使用简单的false!===检查这一点非常重要,因此undefined(根本未传递的参数)仍会更改两个控件。因此,例如$("#control").change()会更改两个控件,但仍然不会循环... you can test that here