I have some jQuery inside javascript functions that changes text on a page and fades it in and out at specific time intervals. I want the functions to run in order one after the other, after each function finishes doing its effects.
dialogueExchange1();
dialogueExchange2();
dialogueExchange3();
function dialogueExchange1() {
$('.text-area1').text("hey");
$('.text-area1').delay(1000).showDialogue(800, 3000).prepareDialogue(800, "hey, are you awake?");
}
function dialogueExchange2() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "wake up").delay(900);
$('.text-area2').text("...");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
}
function dialogueExchange3() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "let's go").delay(900);
$('.text-area2').text("not yet");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
}
The showDialogue
and prepareDialogue
are methods I created that delay and fade text in and out. That is working fine. Basically, I'm just trying to get the text to change in the text area selectors after a specific time. What is currently happening is that all the functions are being run at the same time, thus firing the text changing effects all at the same time. I want dialogueExchange1
to do its effects then when it is done, for dialogueExchange2
to do its effects and then when its done, etc etc.
I have tried messing around with queues, timeouts and callbacks via the solutions below, but I haven't gotten it to do exactly what I want:
How do I chain or queue custom functions using JQuery?
I had this working in the past and doing what I wanted by just having all the text changing methods chained together in one line of code but it just looks bad. Having it broken up in functions and running them in order would make it more organized and helpful to keep track of the text changes and delay times. Thanks!
EDIT: showDialogue
and prepareDialogue
functions as requested
$.fn.showDialogue = function(fadeInTime, showTextTime) {
this.fadeIn(fadeInTime).delay(showTextTime);
return this;
};
$.fn.prepareDialogue = function(fadeOutTime, dialogue) {
this.fadeOut(fadeOutTime, function() {
$(this).html(dialogue);
});
return this;
};
SOLUTION EDIT2: Thanks for the responses everyone and to whoughton for first suggesting the use of promise()
. This is my solution at the moment, but I'm sure I'm going to refactor it down the road and change it now that I have seen Shaunak's answer.
dialogueExchange1();
function dialogueExchange1() {
$('.text-area1').text("hey");
$('.text-area1').delay(1000).showDialogue(800, 3000).prepareDialogue(800, "hey, are you awake?");
$('.text-area1, .text-area2, .text-area3').promise().done(function() {
dialogueExchange2();
});
}
function dialogueExchange2() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "wake up");
$('.text-area3').text("...");
$('.text-area3').delay(1800).showDialogue(800, 1500).fadeOut(800);
$('.text-area1, .text-area2, .text-area3').promise().done(function() {
dialogueExchange3();
});
}
function dialogueExchange3() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "come on let's go");
$('.text-area2').text("hold on");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
}
This way it gives me a lot of flexibility in refining delay times to reflect and mimic a conversation. The next function only runs when the effects within a function are finished, as made possible by promise()
. Here is a jsFiddle link if you want to see it in action.