我有一个包含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;
}
}
}
});
答案 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。