2011-07-26 5 views
6

Estoy tratando de crear una secuencia de animación con jQuery donde una animación comienza después de que la anterior haya terminado. Pero simplemente no puedo entenderlo. Intenté hacer uso de jQuery.queue, pero no creo poder utilizarlo porque parece tener una cola individual para cada elemento en la matriz de jQuery.¿Una secuencia de animación no anidada en jQuery?

necesito algo como:

$('li.some').each(function(){ 
    // Add to queue 
    $(this).animate({ width: '+=100' }, 'fast', function(){ 
     // Remove from queue 
     // Start next animation 
    }); 
}); 

¿Hay una manera de jQuery para hacer esto o tengo que escribir y manejar mi propia cola de forma manual?

Respuesta

16

Usted puede hacer un encargo .queue() para evitar el anidamiento ilimitado ..

var q = $({}); 

function animToQueue(theQueue, selector, animationprops) { 
    theQueue.queue(function(next) { 
     $(selector).animate(animationprops, next); 
    }); 
} 

// usage 
animToQueue(q, '#first', {width: '+=100'}); 
animToQueue(q, '#second', {height: '+=100'}); 
animToQueue(q, '#second', {width: '-=50'}); 
animToQueue(q, '#first', {height: '-=50'}); 

demo en http://jsfiddle.net/gaby/qDbRm/2/


Si, por el Por otro lado, desea realizar la misma animación para una multitud de elementos en E después de la otra, puede utilizar su índice de .delay() la animación de cada elemento de la duración de todos los anteriores ..

$('li.some').each(function(idx){ 
    var duration = 500; 
    $(this).delay(duration*idx).animate({ width: '+=100' }, duration); 
}); 

demo en http://jsfiddle.net/gaby/qDbRm/3/

+0

¡Perfecto! ¡Gracias! – 98374598347934875

2

La devolución de llamada de .animate() en realidad acepta otra .animate(), por lo que todo lo que tendría que hacer sería

$(this).animate({ width: '+=100' }, 'fast', function(){ 
     $(selector).animate({attr: val}, 'speed', function(){ 
}); 
    }); 

y así sucesivamente.

+0

+1 Esta es la manera estándar para encadenar animaciones. Muy simple. – maxedison

+1

Pero no puedes hacer eso en un bucle. ¡Note el 'cada'! – 98374598347934875

1

Puede llamar al siguiente recursivamente.

function animate(item) { 
    var elem = $('li.some').eq(item); 
    if(elem.length) { 
     elem.animate({ width: '+=100' }, 'fast', function() { 
      animate(item + 1); 
     }); 
    } 
} 

animate(0); 
+1

Este también está bien. ¡Gracias! – 98374598347934875

1

¿por qué no crear una cola?

var interval = 0; //time for each animation 
var speed = 200; 

$('li.some').each(function(){ 
    interval++; 
    $(this).delay(interval * speed).animate({ width: '+=100' }, speed); 
}); 

EDIT: añadido parámetro de velocidad

+0

¿Eso es confiable? ¿Estás seguro de que la primera animación se realizará en ese momento? – 98374598347934875

+0

sí, ahora es confiable. Han agregado el parámetro de velocidad – Tarun

1

Gracias a todos respondiendo!

Pensé que debería compartir el resultado de mi pregunta. Aquí hay un plugin jQuery slideDownAll simple que desliza hacia abajo un elemento a la vez en lugar de hacerlo todo a la vez.

(function ($) { 

    'use strict'; 

    $.fn.slideDownAll = function (duration, callback) { 

     var that = this, size = this.length, animationQueue = $({}); 

     var addToAnimationQueue = function (element, duration, easing, callback) { 
      animationQueue.queue(function (next) { 
       $(element).slideDown(duration, easing, function() { 
        if (typeof callback === 'function') { 
         callback.call(this); 
        } 
        next(); 
       }); 
      }); 
     }; 

     return this.each(function (index) { 
      var complete = null, 
       easing = 'linear'; 
      if (index + 1 === size) { 
       complete = callback; 
       easing = 'swing'; 
      } 
      addToAnimationQueue(this, duration/size, easing, complete); 
     }); 
    }; 

} (jQuery)); 

No muy bien prueba, pero de todos modos.

Enjoy !!

Cuestiones relacionadas