以特定顺序运行具有效果的jQuery函数 [英] Running jQuery functions with effects in a specific order

查看:107
本文介绍了以特定顺序运行具有效果的jQuery函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在javascript函数中有一些jQuery,可更改页面上的文本并在特定时间间隔内淡入和淡出文本.我希望函数在每个函数完成其效果后依次运行.

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);
}

showDialogueprepareDialogue是我创建的用于延迟和淡入和淡出文本的方法.很好.基本上,我只是想在特定时间后在文本区域选择器中更改文本.当前正在发生的是所有功能都在同一时间运行,从而同时触发所有文本更改效果.我希望dialogueExchange1在完成时进行效果,dialogueExchange2在完成后进行效果,等等.

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:

如何避免回调链?

如何使用以下方法将自定义函数链接或排队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!

showDialogueprepareDialogue可以按要求运行

$.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;
};

解决方案:感谢大家的回答,并感谢Whoughton首先建议使用promise().目前,这是我的解决方案,但是我确定我将在以后重构它,并在我已经看到Shaunak的回答的情况下对其进行更改.

SOLUTION 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);
}

这样,在细化延迟时间以反映和模仿对话时,它给了我很大的灵活性.下一个功能仅在功能内的效果完成时才能运行,这由promise()来实现.如果您希望看到它,这是一个 jsFiddle链接.

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.

推荐答案

这是一种通过@whoughton指出的诺言来做到这一点的方法:

Here is a a way to do this with promises as @whoughton pointed out:

使用.promise()的解决方案( jsfiddle )

HTML:

<div class="hasEffects effect1"> Div 1</div>
<div class="hasEffects effect2"> Div 2</div>
<div class="hasEffects effect3"> Div 3</div>

<button id="animate">animate</button>

jQuery:

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);
    });

}

这是 jsfiddle

这是如何工作的

您在runAnimation函数中传递了需要链接的所有函数的数组,该函数以递归方式运行,直到完成所有函数.他们使用jquery的.promise()功能在上一个动画完成之前停止下一个功能的执行.

You pass an array of all the functions you need to chain in the runAnimation function which is run recursively until all functions are completed. They way it halts the execution of next function before animation in previous one is completed is using .promise() feature of jquery.

每次runAnimation()运行时,它都会提取数组中的第一个函数并运行它,并且在对该函数执行.proimise().done()后,它将对其余数组再次调用runAnimation().

Everytime the runAnimation() runs, it extracts the first function in the array and runs it, and after .proimise().done() is executed for that function it call runAnimation() again with the remaining array.

真正的诀窍是理解 .promise()的工作方式.它等待所有传递给它的选择器上运行的所有动画.因此,在单个效果功能中,您可以根据需要在任意数量的元素上运行效果.只要您返回正确的选择器就可以了.

The real trick is in understanding how .promise() works. It waits for all animations running on all the selectors passed to it. So in the individual effects function you can run effects on as many elements as you want. As long as you return correct selector you should be good.

例如,假设您想在所有thee效果中对所有3个div运行3种不同的效果.很好,只需从函数返回$("hasEffects"),它将起作用. :)

For example, suppose in all thee effects you wanted to run 3 different effects on all 3 divs. Thats fine, just return $("hasEffects") from the function and it will work. :)

您的情况

在您的特定情况下,这是如何使用此示例的方法.在所有元素上添加一个分组类,例如class="hasEffects".并从动画函数中为它们返回一个jquery选择器.然后使用runAnimation将它们链接起来.这是它的外观:

In your particular case here is how you can use this example. Add a grouping class on all your elements for example class="hasEffects" . And return a jquery selector for them from your animation functions. Then chain them using runAnimation. Here is how it should look:

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);
          });

    }

这篇关于以特定顺序运行具有效果的jQuery函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆