Как правильно упорядочить события анимации с помощью процедур в JQuery - PullRequest
0 голосов
/ 05 марта 2012

Мне было немного трудно пытаться упорядочить некоторые анимационные события в JQuery с рядом других процедур, которые я пытаюсь выполнить одновременно или в определенной последовательности.Вот в основном то, чего я хочу достичь:

  1. Пользователь нажимает кнопку, в результате чего на экране появляется настраиваемое всплывающее окно div.
  2. Всплывающее окно анимируется ввместе с фоном.
  3. Во всплывающем окне отображается сообщение о загрузке, в то время как оно также отправляет (после 1,5-секундной задержки) запрос Ajax на сервер, чтобы выгрузить указанное содержимое, которое затем будет загружено во всплывающее окно..
  4. Затем всплывающее окно загрузки текста должно быть заменено полученным содержимым через боковую сторону.
  5. Когда пользователь читает сообщение, он / она может затем нажать на значок закрытия окнавсплывающее окно или нажмите клавишу выхода, чтобы закрыть всплывающее окно.
  6. Всплывающее окно закрывается с помощью анимации затухания.

С моим текущим кодом (ссылка ниже на JSFiddle), это похоже на работуХорошо, а анимация и последовательность всплывающих окон будут отображаться правильно, при условии, что пользователь сначала закрывает всплывающее окно, а затем нажимает на кнопку, чтобы отобразить его снова.ОДНАКО (и это моя проблема) ... если всплывающее окно остается открытым, и пользователь снова нажимает кнопку, последовательность анимации портится ... кажется, что цепочка событий разваливается - процедура, котораяпоказывает, что всплывающее окно сначала не ждет его закрытия, и вы получаете ужасный эффект.

Есть идеи, как это можно решить?

В идеале, как предполагает логика в коде, мы хотели бы дождаться полной анимации закрытия всплывающего окна, прежде чем снова запустить анимацию показа всплывающего окна.Я все еще немного новичок, когда дело доходит до JQuery, так что прости меня.Я попытался провести некоторое исследование и считаю, что решение может заключаться в использовании Deferreds каким-то умным способом.Тем не менее, я подумал, что вы, ребята, можете предложить отличное, эффективное и современное решение и помешать мне вырвать все мои волосы.=)

Вот мой код (местами несколько упрощенный, но все еще хорошо имитирующий проблему):

http://jsfiddle.net/Nickel3ack/kdcwT/21/

1 Ответ

0 голосов
/ 05 марта 2012

Мне удалось решить мою проблему и правильно настроить последовательность всех событий.Потребовалось некоторое умное использование Отложенных и много проб и ошибок, прежде чем я понял, что я на самом деле делаю.В любом случае, если кому-то нужно это решение для всего, над чем он работает ...

Проблема:
Я хотел, чтобы на моей странице появилось всплывающее окно с сообщением, которое по существу заменило быокно предупреждения браузера для моих целей.Я хотел связать несколько анимаций исчезновения и скольжения, чтобы показать окно сообщения, а затем его содержимое.Я также хотел, чтобы изображение загрузки отображалось в окне сообщения при его первом появлении, в то время как асинхронный запрос отправлялся на сервер.В окне сообщения будет показан ответ.В любом случае, вот как я его настроил ...

В текст моего html я включил контейнер сообщения:

<div id="msg-box">
<div id="msg-box-container">
    <div id="msg-box-headbar">
        <div id="msg-box-title"></div>
        <div id="msg-box-clButton"></div>
    </div>
    <div id="msg-box-content"></div>
    <div id="msg-box-footbar"></div>
</div>
</div>
<div id="msg-box-backdrop"></div>

Как видите, мое окно сообщения также имеетфон (который я настроил как полупрозрачный div, который находится за пределами контейнера окна сообщения).Фон будет отображаться и анимироваться одновременно, но независимо от самого окна сообщения.Это еще одно осложнение, поскольку последовательность и время событий должны выполняться правильно, в противном случае мы получим странные эффекты ... например, фон выполняет одно, а окно сообщения выполняет другое.

Сценарий:
Чтобы сделать мой код немного чище, в первой попытке я создал объектный литерал для окна сообщения с набором функций для управления окном сообщения.Потребовалось много исследований, но в конечном итоге было решено использовать комбинацию цепочек и отложений.В конечном итоге мой код выглядит следующим образом:

    var msgBox = {
    status: 0,
    self: $('#msg-box'),
    title: $('#msg-box-title'),
    cl_button: $('#msg-box-clButton'),
    content: $('#msg-box-content'),
    backdrop: $('#msg-box-backdrop'),

    hideBox: function() {
        var b = this;
        if (b.status == 1) {
            var dfd = $.Deferred();
            b.self.fadeOut(500);
            b.backdrop.fadeOut(500, dfd.resolve);
            b.status = 0;
            return dfd.promise();
        }
    },

    showBox: function(ttl, msg) {
        var b = this;
        if (b.status == 1) {
            $.when(b.hideBox()).then(function() {
                b.doShow();
                b.loadCont(ttl, msg);
            });
        }
        else {
            if(b.backdrop.queue().length > 0) {
                $.when(b.backdrop.queue()).done( function() {
                    b.doShow();
                    b.loadCont(ttl, msg);
                });
            }
            else {
                b.doShow();
                b.loadCont(ttl, msg);
            }
        }
    },

    doShow: function() {
        var b = this;
        b.title.text('Loading...');
        b.content.html('<div id="msg-box-loader"><img id="loading-img" src="/graphics/loader-16.gif" /></div>');
        b.backdrop.height(b.self.height());
        b.self.centerBox($(window).width());
        b.backdrop.centerBox($(window).width());
        b.self.fadeIn('fast');
        b.backdrop.corner('round 6px').fadeTo('fast', 0.6);
    },

    loadCont: function(ttl, msg) {
        var b = this;
        b.content.delay(1500).queue(function(next) {
            b.title.text(ttl);
            b.content.text(msg).slideDown('fast');
            b.backdrop.height(b.self.height()).slideDown('fast');
            b.status = 1;
            next();
        });
    }
};

Как вы можете видеть, в нескольких точках последовательности скрытия / показа я использую Deferreds, чтобы разрешить выполнение определенных событий перед запуском новых.Для справки, это мои привязки:

    // events related to message box
$(document).keydown( function(e) {
    if (e.keyCode == 27) {
        e.preventDefault();
        if(msgBox.status == 1)
            msgBox.hideBox();
    }
});
msgBox.cl_button.hover( function() { $(this).toggleClass('no-hover').toggleClass('hover'); });
msgBox.self.on('click', msgBox.cl_button.selector, function() { msgBox.hideBox();  });
$(window).resize(function() {
    if (msgBox.status == 1) {
        msgBox.self.centerBox($(window).width());
        msgBox.backdrop.centerBox($(window).width());
    }
});

// login form submitted
$('#login-form').submit( function(e) { 
    e.preventDefault();
    var postData = 'async=login&user='+$('#login-user').val()+'&pass='+hex_md5($('#login-pass').val());
    $.ajax({ type: 'POST', url: "index.php", data: postData, 
        success: function(response) { 
            if(response==0) msgBox.showBox('Login Failed', 'Invalid Credentials'); 
            else if(response==1) msgBox.showBox('Success', response); 
            else msgBox.showBox('Internal Error', 'There was an internal error. Please contact the administrator.<br><br>'+response); 
        },
        error: function() { 
            msgBox.showBox('Internal Error', 'There was an internal error. Please contact the administrator.'); 
        } 
    });
});
...