Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以特定顺序运行具有效果的jQuery函数_Javascript_Jquery - Fatal编程技术网

Javascript 以特定顺序运行具有效果的jQuery函数

Javascript 以特定顺序运行具有效果的jQuery函数,javascript,jquery,Javascript,Jquery,我在javascript函数中有一些jQuery,它可以更改页面上的文本,并在特定的时间间隔内淡入淡出。我希望在每个函数完成其效果后,函数按顺序一个接一个地运行 dialogueExchange1(); dialogueExchange2(); dialogueExchange3(); function dialogueExchange1() { $('.text-area1').text("hey"); $('.text-area1').delay(1000).showDialogu

我在javascript函数中有一些jQuery,它可以更改页面上的文本,并在特定的时间间隔内淡入淡出。我希望在每个函数完成其效果后,函数按顺序一个接一个地运行

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

    }