2012-02-16 9 views
0

私は単純だと思うことに苦しんでいます。私は前にJQueryを使わずに普通の古いjavascriptで同じ問題を抱えていたことを知っています。私は何をしようとしています:Jqueryのトリガーイベントはコンテンツを追加しますが、DOMは準備ができていません

//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がstruglingして情報をロードしていないように見えることです。

私は国のトリガーと州の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

ああ、私はまた、$( '#州')を実行しようとしましたレディ(関数(){$(この).val(data.province);}); –

答えて

0

ジャスパーの助けを借りて、私は自分の問題に適用可能な解決策以上のものを見つけたので、私は彼の解決策としてジャスパーを賞賛するつもりですが、答えとして私の印をつけます。私が使用したもの

は、私は、トリガのextraParametersにdata.provinceを渡され、使用して#のpays.changeハンドラで

//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').trigger('change', data.province); 

この方法は、私はジャスパーのようなグローバル変数を作成しませんし、変更イベントのトリガーが県内を通過したかどうかを検出できます。

おかげジャスパー

2

#pays要素のイベントハンドラには、非同期のAJAX呼び出しが含まれています。だから、おそらくすぐ下のコードが実行される前には戻りません。

//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); 

    }); 
}); 

$.get()コールのためのコールバックでは

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

:良い修正は、このコードを実行することです上に使用したループでパフォーマンスが向上することを示すJSPerfがあります。http://jsperf.com/jquery-each-vs-for-loops/2

+0

@gdoron編集していただきありがとうございますが、私が書いた段落は削除されていますので、ロールバックしました。 – Jasper

+0

ああ!ごめんなさい!!!しかし、あなたはまだコードをインデントすることができます... =)答えを読まなかったが、私の+1を得る... – gdoron

+0

foreachのperfテストのおかげで、私は将来のために考慮する。今は一般的に13要素しかないので、実際には減速していませんが、より大きい配列では私はこれを念頭に置いています –

関連する問題