Мне удалось решить мою проблему и правильно настроить последовательность всех событий.Потребовалось некоторое умное использование Отложенных и много проб и ошибок, прежде чем я понял, что я на самом деле делаю.В любом случае, если кому-то нужно это решение для всего, над чем он работает ...
Проблема:
Я хотел, чтобы на моей странице появилось всплывающее окно с сообщением, которое по существу заменило быокно предупреждения браузера для моих целей.Я хотел связать несколько анимаций исчезновения и скольжения, чтобы показать окно сообщения, а затем его содержимое.Я также хотел, чтобы изображение загрузки отображалось в окне сообщения при его первом появлении, в то время как асинхронный запрос отправлялся на сервер.В окне сообщения будет показан ответ.В любом случае, вот как я его настроил ...
В текст моего 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.');
}
});
});