JQuery ждет завершения выполнения кода выше - PullRequest
3 голосов
/ 10 сентября 2010

Я написал некоторый javascript, используя jQuery, чтобы заменить любые списки выбора альтернативами div и ul, так что это даст мне больше контроля над стилем и заставит выпадающие списки выглядеть одинаково в разных браузерах.Приведенный ниже код работает на 99% для меня, но у меня есть одна проблема.В нижней части кода мне пришлось использовать .delay (), чтобы сообщить коду способ ожидания выполнения цикла .each (), чтобы завершить выполнение своих действий.Проблема заключается в том, что до замены остается не менее одной секунды, оставляя вспышку в старых полях выбора.Также я могу предугадать еще одну проблему: если для завершения цикла each () требуется более одной секунды ...

Как получить код внизу для запуска только после запуска каждого циклаи завершить.Также я приветствую любые оптимизации в остальной части кода.

РЕДАКТИРОВАТЬ: некоторые из HTML был удален из кода, поэтому я вставил его: http://pastebin.com/4HFLjHE1


// Check when ready
$(function() {

    // Find dropdowns
    $("select.dropdownreplace").each(function() {replaceDropDown(this);});
    // If document clicked anywhere hide drop downs
    $(document).click(function(event){
        $("div.dropdownreplace ul").hide();
    });

});

function replaceDropDown(that) {
    // Create HTML for new drop down
    // hidden field
    var hiddeninput = $('');
    // div
    var dropdowndiv = $(''+$(":selected", that).text()+'<ul></ul>');

    // loop through values and make li's
    $("option", that).each(function() {
        $("ul", dropdowndiv).append('<li>'+$(this).val()+''+$(this).text()+'</li>');
        // set click handler for this drop down
        $(dropdowndiv).click(function() {
            $("ul", this).show();
            return false;
        });
        // set click handler for link items
        $("a", dropdowndiv).click(function() {
            // Get name of hidden input
            var nameofdropdown = $(this).parent().parent().parent().attr('id');
            var nameofinput = nameofdropdown.replace("dropdownreplacement_", "");
            // set hidden input value to whats been clicked
            $("[name='"+nameofinput+"']").val($(this).parent().find("span").text());
            // set div
            $("div#"+nameofdropdown+" > span").text($(this).text());
            $("div#"+nameofdropdown+" ul").hide();
            return false;
        });
    });

    // Remove drop down then add in replacement html
    $(that).delay(1000).after(hiddeninput);
    $(that).delay(1100).after(dropdowndiv);
    $(that).delay(1200).remove();   
}

Thnaks

Скотт

Ответы [ 2 ]

3 голосов
/ 10 сентября 2010

Внутри вашей функции сравните индекс, который вам передает jquery, с общим количеством элементов, которые у вас есть.

Я не знаю ваш html, но я верю, что вы можете сделать это.

Измените вашу функцию, чтобы она получала индексный параметр, отправляемый jquery.

$("option", that).each(function(index) {

Затем, в конце этой функции, сравните длину с индексом, если они совпадают, то все готово

if ( $('option', that).length == (index +1 ) ) {
    $(that).after(hiddeninput);
    $(that).after(dropdowndiv);
    $(that).remove();
}

Из моих тестов это должно быть то, что вам нужно. Не знаю, есть ли более «стандартный» способ сделать это.

Надеюсь, это поможет

0 голосов
/ 10 сентября 2010

Что вам нужно сделать, это создать функцию обратного вызова l. В вашем each () после начальной функции вы можете указать, что она должна сделать еще несколько вещей, когда она будет завершена:

$("option", that).each(function() {

  <...code...>

}, function() {   
      <...code...>  //this gets performed after the previous function is complete
});
...