简体   繁体   English

[javascript,jQuery]如何在继续播放另一个没有回调的动画之前等待动画完全完成

[英][javascript, jQuery]How to wait for the animation to complete entirely before continuing another animation without callbacks

http://jsfiddle.net/jmztZ/ http://jsfiddle.net/jmztZ/

Above is the link to my problem. 以上是我的问题的链接。 Let say that I have only 1 div, whose content may change via .html(). 假设我只有1个div,其内容可能会通过.html()更改。 I would like to use the div to change its content and display itself using animate() or show() etc. However, when there are 2 functions that manipulate the div, browser's speed is too fast which seems to skip the first .html() function. 我想使用div来更改其内容并使用animate()或show()等显示自身。但是,当有两个操作div的函数时,浏览器的速度太快,似乎跳过了第一个.html( )功能。

Question: How could I wait until the first function (aka "go()" in the fiddle) to completely execute (which includes changing contents .html() and all animation) before firing the second function (aka "went"). 问题:我如何才能等到第一个功能(即小提琴中的“ go()”)完全执行(包括更改内容.html()和所有动画)之后,再触发第二个功能(即“ went”)。

Attempts: 尝试次数:

Note: Even though those attempts of mine seems to execute the animation respectively on queue, the html() function can never wait. 注意:即使我的那些尝试似乎分别在队列上执行动画,html()函数也永远无法等待。 Take a look at the fiddle again. 再看看小提琴。 Also, I've tried several methods found on Stackoverflow, and they all end up the same. 另外,我尝试了在Stackoverflow上找到的几种方法,但它们最终都一样。

I've tried using: 我试过使用:

//Regular way, obviously didn't work
go(); went();

And using Deferred: 并使用Deferred:

$.Deferred().done(go, went).resolve();

And also self-called function: 还有自调用函数:

var f = [go, went]; c = 0;
(function selfCall(){
    if (c >= f.length) return;
    f[c].call(); c++;
    selfCall();
})();

But none of them seems to work properly. 但是它们似乎都无法正常工作。

So to finalize, I would have an Array which can use .push() to push in any number of functions to execute, the functions are all about manipulating the content of the div and animate it. 所以最终,我将拥有一个可以使用.push()推入要执行的函数的数组,这些函数都是关于操纵div的内容并对其进行动画处理的。 I would like to know the way to properly execute all functions from that Array, one by one, and the next one must wait until the current one is finish. 我想知道一种正确地从该数组正确执行所有功能的方法,而下一个必须等​​到当前函数完成为止。

You cant do it without callback, but here a work arround. 您不能没有回调来做到这一点,但是这是一项工作。 When calling the function, send selfCall as parameter: 调用函数时,将selfCall作为参数发送:

f[c].call(null, selfCall); c++; //null = this in function, but you don't use this.

Then, in the go function, do this : 然后,在go函数中,执行以下操作:

function go(callback) {
    $("#foo").html("GO");
    $("#foo").show("drop", 750).hide("explode", 500, callback);
}

Fiddle : http://jsfiddle.net/jmztZ/1/ 小提琴: http : //jsfiddle.net/jmztZ/1/

Try this. 尝试这个。

function go() {
    $("#foo").html("GO");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function going() {
    $("#foo").html("going");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function gone() {
    $("#foo").html("gone");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function went() {
    $("#foo").html("WENT");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
var arr = [go, going, gone, went],
    thisItem;

//randomize array
arr = arr.sort((function() { return 0.5 - Math.random();}));

function getNextArrayFn() {
    thisItem = arr.shift();
    thisItem().done(getNextArrayFn);
};
getNextArrayFn();

Here is the fiddle: http://jsfiddle.net/jmztZ/31/ 这是小提琴: http : //jsfiddle.net/jmztZ/31/

I think you may try a technic called Monad —— But what is Monad ? 我想您可以尝试一种叫做Monad的技术-但是Monad是什么? I can not explain it properly. 我无法正确解释。

So , "Please show me the code!" 所以,“请告诉我代码!”

We have some async functions in a array pipequeue ,each function in pipequeue must be a deferred instance . 我们有一个数组一些异步函数pipequeue ,在每个功能pipequeue必须是一个deferred的实例。 the function can be async. 该功能可以是异步的。 they will executed one by one. 他们将一一执行。

like this : drop explode drop2 explode2 are four async animation process , each one returned a jQuery promise . 像这样: drop explode drop2 explode2是四个异步动画过程,每个过程返回一个jQuery promise

the complete code is at jsbin: http://jsbin.com/ikovof/2/ 完整的代码在jsbin上: http ://jsbin.com/ikovof/2/

var $el = $("#foo");
function drop(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.html("GO");
  $el.show("drop",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function explode(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.hide("explode",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function drop2(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.html("WENT");
  $el.show("drop",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function explode2(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.hide("explode",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

var pipequeue = [drop,explode,drop2]

pipequeue.push(explode2);

pipe(unit(),pipequeue);

You can push or pop pipequeue . 您可以pushpop pipequeue every fn in pipequeue is without coupling ! pipequeue每个fn都没有耦合!

But if you think pipe(unit(),pipequeue) is a bit of ... 但是如果您认为pipe(unit(),pipequeue)有点...

you can wrap unit() call into a function: 您可以将unit()调用包装到一个函数中:

function pipePromise(pipequeue){
  pipe(unit(),pipequeue);
}
// then your call can be quite neat now  
pipePromise(pipequeue);

I like Mr. Smee's Answer , but there is another option. 我喜欢史密斯先生的答案 ,但还有另一种选择。 Write the html in a callback to .hide(0, callback) : 将html写入.hide(0, callback)

$("#foo").hide(0, function(){ $(this).html("GO"); });

http://jsfiddle.net/jmztZ/34/ http://jsfiddle.net/jmztZ/34/

You can even call them sequentially that way: 您甚至可以按以下方式依次调用它们:

http://jsfiddle.net/jmztZ/35/ http://jsfiddle.net/jmztZ/35/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM