when then fast animations animate jquery asynchronous jquery-animate synchronous

then - Animación sincrónica de jQuery.



jquery ui animate (7)

En muchos casos deseo que la animación se ejecute de forma sincrónica. Especialmente cuando deseo hacer una serie de animaciones secuenciales.

¿Hay una manera fácil de hacer que una función de jQuery animate sincronice?

La única forma en que pensé es establecer una marca como verdadera cuando la animación ha terminado y esperar a que aparezca.


Aquí hay un módulo que armé hace un tiempo para ayudar a ejecutar animaciones secuencialmente.

Uso:

var seq = [ { id: ''#someelement'', property:''opacity'', initial: ''0.0'', value:''1.0'', duration:500 }, { id: ''#somethingelse'', property:''opacity'', value:''1.0'', duration: 500 } ]; Sequencer.runSequence(seq);

var Sequencer = (function($) { var _api = {}, _seq = {}, _seqCount = 0, _seqCallback = {}; function doAnimation(count, step) { var data = _seq[count][step], props = {}; props[data.property] = data.value $(data.id).animate(props, data.duration, function() { if (step+1 < _seq[count].length) { doAnimation(count, ++step); } else { if (typeof _seqCallback[count] === "function") { _seqCallback[count](); } } }); } _api.buildSequence = function(id, property, initial, steps) { var newSeq = [], step = { id: id, property: property, initial: initial }; $.each(steps, function(idx, s) { step = {}; if (idx == 0) { step.initial = initial; } step.id = id; step.property = property; step.value = s.value; step.duration = s.duration; newSeq.push(step); }); return newSeq; } _api.initSequence = function (seq) { $.each(seq, function(idx, s) { if (s.initial !== undefined) { var prop = {}; prop[s.property] = s.initial; $(s.id).css(prop); } }); } _api.initSequences = function () { $.each(arguments, function(i, seq) { _api.initSequence(seq); }); } _api.runSequence = function (seq, callback) { //if (typeof seq === "function") return; _seq[_seqCount] = []; _seqCallback[_seqCount] = callback; $.each(seq, function(idx, s) { _seq[_seqCount].push(s); if (s.initial !== undefined) { var prop = {}; prop[s.property] = s.initial; $(s.id).css(prop); } }); doAnimation(_seqCount, 0); _seqCount += 1; } _api.runSequences = function() { var i = 0. args = arguments, runNext = function() { if (i+1 < args.length) { i++; if (typeof args[i] === "function") { args[i](); runNext(); } else { _api.runSequence(args[i], function() { runNext(); }); } } }; // first we need to set the initial values of all sequences that specify them $.each(arguments, function(idx, seq) { if (typeof seq !== "function") { $.each(seq, function(idx2, seq2) { if (seq2.initial !== undefined) { var prop = {}; prop[seq2.property] = seq2.initial; $(seq2.id).css(prop); } }); } }); _api.runSequence(arguments[i], function (){ runNext(); }); } return _api; }(jQuery));


Creo que deberías echar un vistazo al método jQuery queue() .

El doc. De queue () no solo explica las animaciones de jQuery realmente no bloquean la IU, y en realidad las pone en cola una tras otra.

También proporciona una manera de hacer que sus animaciones y llamadas de funciones sean secuenciales (este es mi mejor entendimiento de lo que quiere decir con " síncrono "), como:

$("#myThrobber") .show("slow") // provide user feedback .queue( myNotAnimatedMethod ) // do some heavy duty processing .hide("slow"); // provide user feedback (job''s myNotAnimatedMethod() { // or animated, just whatever you want anyhow... // do stuff // ... // tells #myThrobber''s ("this") queue your method "returns", // and the next method in the queue (the "hide" animation) can be processed $(this).dequeue(); // do more stuff here that needs not be sequentially done *before* hide() // }

Esto es, por supuesto, una exageración con el procesamiento asíncrono; pero si su método es en realidad un método simple y sincrónico de javascript, esa podría ser la manera de hacerlo.

Espero que esto ayude, y lo siento por mi pobre inglés ...



Estoy de acuerdo con @SLaks en este caso. Debería usar las devoluciones de llamada de jQuery para animaciones dadas para crear su animación sincrónica. Básicamente, puede tomar lo que tenga para su animación actual y dividirlo así:

$yourClass = $(''.yourClass''); $yourClass.animate({ width: "70%" }, ''slow'', null, function() { $yourClass.animate({ opacity: 0.4 }, ''slow'', null, function() { $yourClass.animate({ borderWidth: "10px" }); }); });


jQuery no puede hacer animaciones síncronas.

Recuerda que JavaScript se ejecuta en el hilo de la interfaz de usuario del navegador.

Si realiza una animación sincrónica, el navegador se congelará hasta que la animación termine.

¿Por qué necesitas hacer esto?

Probablemente debería usar el parámetro de devolución de llamada de jQuery y continuar su código de método en la devolución de llamada, como esto:

function doSomething() { var thingy = whatever; //Do things $(''something'').animate({ width: 70 }, function() { //jQuery will call this method after the animation finishes. //You can continue your code here. //You can even access variables from the outer function thingy = thingy.fiddle; }); }

Esto se llama un cierre.


jQuery proporciona una devolución de llamada de "paso" para su método .animate (). Puedes enganchar a esto para hacer animaciones síncronas:

jQuery(''#blat'').animate({ // CSS to change height: ''0px'' }, { duration: 2000, step: function _stepCallback(now,opts) { // Stop browser rounding errors for bounding DOM values (width, height, margin, etc.) now = opts.now = Math.round(now); // Manipulate the width/height of other elements as ''blat'' is animated jQuery(''#foo'').css({height: now+''px''}); jQuery(''#bar'').css({width: now+''px''}); }, complete: function _completeCallback() { // Do some other animations when finished... } }


jQuery puede hacer animaciones síncronas. Mira esto:

function DoAnimations(){ $(function(){ $("#myDiv").stop().animate({ width: 70 }, 500); $("#myDiv2").stop().animate({ width: 100 }, 500); }); }