0

我创建了一个小脚本来将变量更改为两个不同的字段 ID。

var locationSelect = '#shipping_country_code';

function shippingColumn() {
    $(locationSelect).change(function(){
        var location = $(this).val();
        $('.shipping_country_code').val(location);
    });
}
shippingColumn();

$('#order_shipping_same_as_billing').change(function() {
    var checked = $(this).is(':checked');
    if (checked) {
        locationSelect = '#country_code';
    } else {
        locationSelect = '#shipping_country_code';
    }   
    shippingColumn();
});

该代码有效,但存在一个问题。该变量默认设置为#shipping_country_code。如果复选框被更改,变量将更改为#country_code。到现在为止还挺好。然后再次更改复选框,由于某种原因,这两个字段都会触发变量 locationSelect 的更改。

谁能看到我的代码中会发生这种情况的原因?

4

1 回答 1

3

您正在将更改侦听器绑定到元素。无论您在执行路径中进一步更改哪些变量,该侦听器仍将被绑定。您需要取消绑定侦听器,或使用 jQuery 的.one.

更新。我意识到.one这并不完全是你所需要的。它将一个监听器绑定到一个只会触发一次然后注销的事件。您需要一些可能会触发多次的东西,并根据状态取消注册。为了能够注销事件,重要的是引用指向完全相同的函数(而不仅仅是相同的函数),因此您不能内联定义事件处理程序。

取消注册事件的示例可能如下所示:

function selectChange() {
    var location = $(this).val();
    $('.shipping_country_code').val(location);
}

function shippingColumn() {
    $('#shipping_country_code, #country_code').unbind('change', selectChange);
    $(locationSelect).bind('change', selectChange);
}

演示(为了清楚起见,我添加了一个活动类)。

现在。绑定和解绑监听器时很容易迷路。您要做的最后一件事(通常)是意外注册同一个侦听器两次。我会建议一种不同的方法,我认为这会产生更少的问题,在这种情况下,您将一劳永逸地绑定事件处理程序, at DOMReady,这将始终为两个元素触发,然后您使用更改侦听器来检查您的状态变量,看看是否应该处理事件。

$('#shipping_country_code, #country_code').change(function() {
    if(!$(this).is(locationSelect)) return;
    var location = $(this).val();
    $('.shipping_country_code').val(location);
});

演示

您会注意到,对于您的用例,您实际上不必在此解决方案中使用状态变量;评估当前事件是否应该被处理几乎和它发生时一样容易:

$('#shipping_country_code, #country_code').change(function() {
    var sameAsBilling = $('#order_shipping_same_as_billing').is(':checked');
    if((this.id == 'country_code' && !sameAsBilling) ||
       (this.id == 'shipping_country_code' && sameAsBilling)) return;
    var location = $(this).val();
    $('.shipping_country_code').val(location);
});

演示

侦听器内部的逻辑变得有点复杂,但所有逻辑都包含在一个侦听器中,因此这可能会使整个代码在更大的项目中不那么复杂。

于 2013-06-19T13:58:38.467 回答