2012-02-16 3 views
0

Я борюсь с чем-то, что, по моему мнению, будет простым. Я знаю, что у меня была такая же проблема в простом javascript без JQuery. Что я пытаюсь сделать, это:Событие триггера 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'); 
     } 
    }); 
}); 

В основном это вызывает подстановки сценарий PostalCode и возвращает объект с данными. Сами данные верны, я могу предупредить об этом, и он показывает, что это хорошо. Проблема заключается в том, что триггер изменения на #pays (страна на английском языке) перезагружает информацию в #province (state), и похоже, что DOM борется, а не загружает информацию.

Если я предупреждаю между триггером по стране и регионом провинции, я могу правильно установить провинцию. Метод я использую для добавления провинций к коробке провинции является следующее:

//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') вал (data.province).

Это я? Или есть волшебный трюк, который я не могу найти ...

+0

О, и я также пытался сделать $ ('# провинция') готовы (функция() {$ (это) .val (data.province);}). –

ответ

0

С помощью 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

2

Обработчик события для элемента #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

+0

@gdoron Спасибо за редактирование, но он удалил абзац, который я написал, поэтому я свернул его назад. – Jasper

+0

Ох! Прости!!! Но вы все равно можете отступать от кода правильно ... =) Не прочитал ответ, но получите мой +1 ... – gdoron

+0

Спасибо за перфекционные тесты на foreach, я буду учитывать это в будущем. Сейчас у меня всего 13 элементов в целом, поэтому он не замедляется, но с большими массивами я обязательно буду помнить об этом –

Смежные вопросы