Не удалось запустить функцию, которая включает setTimeout () дважды. Странное поведение - PullRequest
0 голосов
/ 28 декабря 2011

У меня проблема с функциями JavaScript setTimeout () и setInterval () функции.

В основном моя функция обрабатывает действие отправки формы. После нажатия кнопки «отправить» все данные из указанной формы сериализуются и отправляются через ajax, который вызывает « functionName ». functionName возвращает 1 , если все в порядке, или код ошибки , если нет. После этого всплывающее окно div создается с успешное сообщение или код ошибки . Всплывающее окно div должно отображаться в течение 6 секунд. Пользователь должен увидеть обратный отсчет от 6 до 0 . При достижении нуля страница перенаправляется, если задан аргумент перенаправления. если аргумент перенаправления не задан, всплывающее окно div удаляется. Я использую функцию setTimeout () , которая вызывает некоторые проблемы. до этого я использовал функцию setinterval и проблема выглядела почти так же.

Когда функция handleSubmit запускается в первый раз (щелчок кнопки «Отправить»), функция обратного отсчета работает отлично, но когда я снова запускаю эту функцию, происходят странные вещи. Я использую onclick для запуска своей функции.

<input type="submit" name="submit" onclick="handleSubmit('formName', 'functionName', 'redirectURL')" value="send" />

Вот определение моей функции:

function handleSubmit(formName, functionName, redirectLocation){
    $('form#' + formName).submit(function(event){
        event.preventDefault();

        $.ajax({
            type: "POST",
            url: '/ajax/functions/module=none,method=' + functionName,
            data: $('form#' + formName).serialize(),
            success: function(data){

                var div = $('<div></div>').addClass('messages');
                div.appendTo('.content_block');

                var exitButton = $('<p class="title" style="overflow: hidden; margin-top:10px;"></p>');

                /**
                  * If the redirectLocation argument is empty we create HTML button with
                  * removeElement function which removes HTML popup DIV with class "messages"
                  * but if redirectLocation argument is provided we create HTML button with
                  * redirect function so after clicking we will be redirected.
                  * This buttons are created if we dont want to wait 6 seconds
                  */ 

                if(redirectLocation=='')
                    var button = $('<img title="Close this message" onclick="removeElement(\'.messages\')" src="/public/images/close.png" alt="Close message" style="cursor: pointer; float: right; padding-right: 10px;" width="16" height="16"  />');
                else
                    var button = $('<img title="Close this message" onclick="redirect(\''+ redirectLocation + '\')" src="/public/images/close.png" alt="Wyłącz komunikat" style="cursor: pointer; float: right; padding-right: 10px;" width="16" height="16"  />');


                exitButton.html(button);
                div.html(exitButton);
                var message = $('<p></p>');

              /**
                * Data recieved from AJAX 
                */

                if(data==1){

                    message.html("Data was successful uploaded");
                    message.appendTo(div);

                    var timer = $('<span id="timer"></span>');
                    timer.html('Message will be closed after: <b id="show-time">6</b> sec.');
                    timer.appendTo(div);

                    setTimeout("timedCount(" + redirectLocation + ")", 1000);                //this is countdown function

                }else{
                    message.html("Error: " + functionName + ".");
                    var error = $('<p>Error content: ' + data + '</p>');
                    error.appendTo(message);
                    message.appendTo(div);

                    var timer = $('<span id="timer"></span>');
                    timer.html('Message will be closed after: <b id="show-time">6</b> sek.');
                    timer.appendTo(div);
                    setTimeout("timedCount(" + redirectLocation + ")", 1000);                //this is countdown function
                }

                return true;
            }});
    });

}

И моя функция timedCount, которая должна отсчитывать от 6 до 0, выглядит следующим образом.

  function timedCount(redirectLocation){
    timeCounter = $('#show-time').html();
    updateTime = parseInt(timeCounter)- 1;
    $("#show-time").html(updateTime);
    t = setTimeout("timedCount()", 1000);
    if(updateTime == 0){
        if(redirectLocation){
            $('#timer').html('Redirecting...');
            window.location = (redirectLocation);
        }else{
            $('.messages').remove();
            clearTimeout(t);  
        }

    }
}

РЕЗЮМЕ. Первый раз (когда не используется redirectLocation ) функция hendleSubmit работает нормально. Но когда кнопка отправки нажимается второй раз, моя функция timedCount не ведет обратный отсчет с 6 до 0, а setTimeout работает в фоновом режиме вечно. Я понятия не имею, что вызывает такое поведение.

1 Ответ

0 голосов
/ 28 декабря 2011

Вы связываете обработчик события submit для формы внутри обработчика события click для кнопки отправки. Это означает, что при каждом последующем нажатии кнопки отправки добавляется другой обработчик события для события submit для формы.

Как насчет объявления обработчика событий submit для всех форм в более глобальном пространстве? Просто переместите $('form#' + formName).submit(function(event){...}) за пределы функции handleSubmit: $('form').submit(function(event){...}).

Также вы должны использовать анонимную функцию в ваших объявлениях setTimeout (это позволит избежать использования eval(), когда в этом нет необходимости):

setTimeout(function () {
    timedCount(redirectLocation)
}, 1000);
...