Javascript 以特定顺序运行具有效果的jQuery函数
我在javascript函数中有一些jQuery,它可以更改页面上的文本,并在特定的时间间隔内淡入淡出。我希望在每个函数完成其效果后,函数按顺序一个接一个地运行Javascript 以特定顺序运行具有效果的jQuery函数,javascript,jquery,Javascript,Jquery,我在javascript函数中有一些jQuery,它可以更改页面上的文本,并在特定的时间间隔内淡入淡出。我希望在每个函数完成其效果后,函数按顺序一个接一个地运行 dialogueExchange1(); dialogueExchange2(); dialogueExchange3(); function dialogueExchange1() { $('.text-area1').text("hey"); $('.text-area1').delay(1000).showDialogu
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);
}
showDialogue
和prepareDialogue
是我创建的延迟和淡入淡出文本的方法。这很好。基本上,我只是想让文本在特定时间后在文本区域选择器中更改。目前发生的情况是,所有函数都在同一时间运行,从而同时触发文本更改效果。我希望dialogueExchange1
在完成时执行其效果,对于dialogueExchange2
执行其效果,然后在完成时执行其效果,等等
我尝试过通过下面的解决方案来处理队列、超时和回调,但我还没有让它完全按照我的要求来做:
我过去一直在做这件事,我只是想让所有的文本更改方法在一行代码中链接在一起,但它看起来很糟糕。将其分解成函数并按顺序运行将使其更有条理,有助于跟踪文本更改和延迟时间。谢谢
编辑:showDialogue
和prepareDialogue
按要求运行
$.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;
};
解决方案EDIT2:感谢大家的回复,感谢沃顿首次建议使用promise()
。这是我目前的解决方案,但我确信我会在以后重构它,现在我已经看到了Shaunak的答案
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);
}
通过这种方式,我可以灵活地调整延迟时间,以反映和模拟对话。下一个函数仅在函数内的效果完成时运行,这是通过promise()
实现的。如果你想看到它的实际应用,这里有一个例子。这个怎么样:
dialogueExchange1();
function dialogueExchange1() {
$('.text-area1').text("hey");
$('.text-area1').delay(1000).showDialogue(800, 3000).prepareDialogue(800, "hey, are you awake?");
dialogueExchange2();
}
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();
});
}
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);
}
我建议使用承诺系统,jQuery有自己的实现:
通常,在jQuery中执行此操作的方式有两种。首先介绍一下Javascript中的异步内容 当您调用
fadeOut()
时,它的行为就像有两个执行线程一样。其中一个线程开始对元素进行一系列更改,使其越来越不可见。另一个线程继续执行fadeOut()
之后的命令。也许是另一个屏幕元素的淡入。你需要仔细阅读它是如何工作的,因为我使用的“线程”这个词非常松散,细节也不同。但你可以把它看作是同时发生的两件事。这就是为什么您可以同时看到所有元素的动画效果。(有时候,这是我们想要的行为。)
使动画按顺序发生的一种方法是这样。将动画调用串在同一元素上:
$(whatever).delay(400).fadeIn(300).
因此,同一元素上的动画将等待先前排队的动画完成,然后再开始
另一种方式允许多个元素按顺序更改:
$(whatever).delay(400).fadeOut(300, function() {
$(whateverelse).fadeIn(400);
}
直到fadeOut()完成,才调用该函数。因此,fadeIn()直到另一个完成后才开始
您的情况更加复杂,部分原因是这两种方法,但可以使用这两种方法来完成。您的方法可能需要接受一个附加参数,该参数是动画完成后要调用的函数
注意:由于您的两个方法只处理“this”并返回“this”,因此它们会将动画添加到您正在处理的相同元素中。这些动画应该保持顺序
只有当一个元素需要动画来等待另一个元素的动画时,才需要第二种形式
注2:我注意到函数将动画挂在相同的元素上,因此您可以执行以下操作:
function dialogueExchange2() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "wake up").delay(900,
function() {
$('.text-area2').text("...");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
});
}
function dialogueExchange3() {
$('.text-area2').delay(1, function() { // this just makes #3 wait for #2 to finish
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "let's go").delay(900,
function() {
$('.text-area2').text("not yet");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
});
});
}
dialogueExchange1();
dialogueExchange2();
dialogueExchange3();
当你打电话给他们时,你是这样做的:
function dialogueExchange2() {
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "wake up").delay(900,
function() {
$('.text-area2').text("...");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
});
}
function dialogueExchange3() {
$('.text-area2').delay(1, function() { // this just makes #3 wait for #2 to finish
$('.text-area1').delay(900).showDialogue(800, 4000).prepareDialogue(800, "let's go").delay(900,
function() {
$('.text-area2').text("not yet");
$('.text-area2').delay(1200).showDialogue(800, 1500).fadeOut(800);
});
});
}
dialogueExchange1();
dialogueExchange2();
dialogueExchange3();
下面是一把小提琴,它展示了你正在尝试做的事情的一个非常简单的版本。。我想。 每个项目都应该在设置的延迟后运行,因为它们都是异步的。 例如,如果第一个动画长度为1500ms,并且您希望文本在该动画完成后更改300ms,则该动画将延迟1800ms。。。希望这是有道理的
var timeoutQueue = [],
$ta1 = $('.text-area1'),
$ta2 = $('.text-area2');
//Each of the DELAY_IN_MS in the functions should be the exact point in ms where the animation should occur.
timeoutQueue.push(
setTimeout(function(){
$ta1.text("hey");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.showDialogue(800, 3000);
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.prepareDialogue(800, "hey, are you awake?");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.showDialogue(800, 4000);
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.prepareDialogue(800, "wake up");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.text("...");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.showDialogue(800, 1500)
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.fadeOut(800)
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.showDialogue(800, 4000);
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta1.prepareDialogue(800, "let's go");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.text("not yet");
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.showDialogue(800, 1500);
}, DELAY_IN_MS)
);
timeoutQueue.push(
setTimeout(function(){
$ta2.fadeOut(800);
}, DELAY_IN_MS)
);
编辑:
编辑2:
我认为没有比这更有效的方法了,但你可以用循环的善意来实现。这里有一种方法可以通过@woughton指出的承诺来实现这一点: 使用.promise()解决方案() Html: 这是你的电话号码 这是如何工作的 在runAnimation函数中传递需要链接的所有函数的数组,该函数递归运行,直到所有函数完成。在上一个函数中的动画完成之前,它停止执行下一个函数的方式是使用jquery的
.promise()
特性
每次运行runAnimation()
时,它都会提取数组中的第一个函数并运行它,然后对该函数执行.proimise().done()
,并使用剩余数组再次调用runAnimation()
真正的诀窍在于理解如何工作。它等待传递给它的所有选择器上运行的所有动画。因此,在“单个效果”功能中,可以对任意多个元素运行效果。只要您返回正确的选择器,您就应该是好的
例如,假设在所有电子特效中,您希望在所有3个div上运行3个不同的特效。这很好,只需从函数返回$(“hasEffects”)
,它就会工作。:)
在您的情况下
在您的特殊情况下,这里是如何使用此示例的。在所有元素上添加分组类,例如class=“hasEffects”
。并从动画函数中为它们返回jquery选择器。然后使用runAnimation链接它们。这是应该怎么做的
effects1 = function(){
$(".effect1").effect("shake", {}, 1000);
return $(".effect1");
// or you can return $(".hasEffects"); if you are running effects on multiple elements
};
effects2 = function(){
$(".effect2").effect("shake", {}, 1000);
return $(".effect2");
};
effects3 = function(){
$(".effect3").effect("shake", {}, 1000);
return $(".effect3");
};
$("#animate").click(function(){
runAnimations([effects1,effects2,effects3]);
});
runAnimations = function(functionArray) {
//extract the first function
var func = functionArray.splice(0, 1);
//run it. and wait till its finished
func[0]().promise().done(function() {
//then call run animations again on remaining array
if (functionArray.length > 0) runAnimations(functionArray);
});
}
function dialogueExchange1() {
$('.text-area1').text("hey");
$('.text-area1').delay(1000).showDialogue(800, 3000).prepareDialogue(800, "hey, are you awake?");
return $(".hasEffects");
}
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);
return $(".hasEffects");
}
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);
return $(".hasEffects");
}
runAnimations([dialogueExchange1,dialogueExchange2,dialogueExchange3]);
runAnimations = function(functionArray){
var func = functionArray.splice(0,1);
func[0]().promise().done(function(){
if(functionArray.length > 0 ) runAnimations(functionArray);
});
}