Jquery触发器事件附加内容但DOM未准备就绪

时间:2012-02-16 19:22:13

标签: jquery

我正在努力做一些我认为很简单的事情。我知道我以前在没有JQuery的普通旧javascript中遇到了同样的问题。我尝试做的是:

//When the postal code blurs, lookup the city, country, province
$('#codePostal').blur(function(){
    $.get('/fr/radio-telethon/ajax_code_postal.php', {code_postal: $('#codePostal').val()}, function(data){
        if(data.code_postal.toLowerCase() == $('#codePostal').val().toLowerCase()){
            $('#ville').val(data.ville);
            $('#pays').val(data.pays);
            $('#pays').trigger('change');
            $('#province').val(data.province);
            $('#province').trigger('change');
        }
    });
});

这基本上调用了邮政编码查找脚本并返回带有数据的对象。数据本身是正确的,我可以提醒它,它显示正常。问题是#pays(英文国家)的更改触发器会重新加载#province(state)中的信息,看起来DOM正在捣乱并且没有加载信息。

如果我在国家的触发器和省的val之间发出警报,我可以正确设置省份。我用于将省份添加到省框的方法如下:

//Empty the provinces
$('#province').empty();

//Get the new data
$.get('/include/radio-telethon/formulaire-ajax.php', {pays: code}, function(data){

    //Loop the items
    for(i in data.options){
        $('#province').append('<option value="'+data.options[i].value+'">'+data.options[i].label+'</option>');
    }

    //Setup the label
    $('#labelProvince').html(data.label);

});

所以我的猜测是,APPEND搞砸了所有东西并使整个DOM徘徊,这就是为什么我似乎无法做$('#province')。val(data.province);

是我吗?或者是否有一个我似乎找不到的魔术......

2 个答案:

答案 0 :(得分:2)

change元素的#pays事件处理程序包含一个异步的AJAX调用。所以它可能不会在下面的代码运行之前返回。一个很好的解决方法是运行此代码:

        $('#province').val(data.province);
        $('#province').trigger('change');

$.get()来电的回调中:

//setup a variable to store the province once it's returned from the server
var province = '';
$('#codePostal').blur(function(){
    $.get('/fr/radio-telethon/ajax_code_postal.php', {code_postal: $('#codePostal').val()}, function(data){
        if(data.code_postal.toLowerCase() == $('#codePostal').val().toLowerCase()){
            $('#ville').val(data.ville);
            $('#pays').val(data.pays);
            $('#pays').trigger('change');

            //save the province so it can be used later
            province = data.province;
        }
    });
});

//Get the new data
$.get('/include/radio-telethon/formulaire-ajax.php', {pays: code}, function(data){

    //Loop the items
    for(i in data.options){
        $('#province').append('<option value="'+data.options[i].value+'">'+data.options[i].label+'</option>');
    }

    //Setup the label
    $('#labelProvince').html(data.label);

    //update the #province element using the saved province variable
    $('#province').val(province).trigger('change');
});

您的代码也可以利用一些优化:

var province = '';
$('#codePostal').blur(function(){
    var thisValue = this.value;//cache `this.value` since it's used multiple times
    $.get('/fr/radio-telethon/ajax_code_postal.php', {code_postal: thisValue}, function(data){
        if(data.code_postal.toLowerCase() == thisValue.toLowerCase()){
            $('#ville').val(data.ville);
            $('#pays').val(data.pays).trigger('change');//notice the function chaining
            province = data.province;
        }
    });
});
$('#pays').change(function () {

    //Get the new data
    $.get('/include/radio-telethon/formulaire-ajax.php', {pays: code}, function(data){
        var output = [];

        //Loop the items, using a much faster loop, also buffering the output so it gets added to the DOM at once which creates A LOT less overhead

        for(var i = 0, len = data.options.length; i < len; i++){
            output.push('<option value="'+data.options[i].value+'">'+data.options[i].label+'</option>');
        }

        //this will empty the #province element and append the output at once
        $('#province').html(output.join('')).val(province).trigger('change');

        //Setup the label
        $('#labelProvince').html(data.label);

    });
});

这是一个JSPerf,用于显示我在上面使用的循环中的性能提升:http://jsperf.com/jquery-each-vs-for-loops/2

答案 1 :(得分:0)

在Jasper的帮助下,我发现了一个不仅适用于我的问题的解决方案,所以我会对Jasper的解决方案竖起大拇指,但我会将我的标记作为答案。

我使用的是我将data.province传递给触发器的extraParameters并添加了

//When country changes, show/hide the province/region
$('#pays').change(function(event, province){

    ........ other code .......

    //If there is a province in the parameter, set it
    if(province !== 'undefined'){
        $('#province').val(province);
        $('#province').trigger('change');
    }


    ........ other code .......

});
#pays.change处理程序中的

使用:

$('#pays').trigger('change', data.province);

这样,我不会创建像Jasper那样的全局变量,我仍然可以检测更改事件的触发器是否在省内传递。

感谢Jasper