我正在努力做一些我认为很简单的事情。我知道我以前在没有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);
是我吗?或者是否有一个我似乎找不到的魔术......
答案 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