2010-02-26 18 views
15

Estoy animando algunos elementos de error/validación en una página. Quiero que reboten y se destaquen, pero al mismo tiempo si es posible. Esto es lo que estoy haciendo actualmente:¿Cómo puedo ejecutar múltiples efectos de jquery simultáneos?

var els = $(".errorMsg"); 
els.effect("bounce", {times: 5}, 100); 
els.effect("highlight", {color: "#ffb0aa"}, 300); 

Esto hace que los elementos al primer bote, y luego ser puesto de relieve, y me gustaría que ocurrir simultáneamente. Sé que con .animate() puede especificar queue:false en las opciones, pero no quiero usar animate porque los efectos preestablecidos "rebotar" y "resaltar" son exactamente lo que quiero.

He intentado simplemente encadenar las llamadas como els.effect().effect(), y eso no funciona. También intenté poner queue:false en el objeto de opciones que paso, y eso no funciona.

+0

¿Qué versión de jQuery se utiliza? –

+0

1.4.2, interfaz de usuario 1.7.2. Por lo tanto, último estable de ambos en el momento de escribir esto. –

Respuesta

8

Ok, esta es una solución muy personalizada que combina los efectos de rebote y resaltado. Prefiero ver algún tipo de soporte de jquery para combinar estos más fácilmente, especificando {queue: false}, pero no creo que sea así de simple.

Lo que hice fue tomar jquery.efectos.bounce.js y jquery.effects.highlight.js (de jquery-ui-1.8rc3), y combinar el código de los dos como sugirió DaveS, para crear un nuevo efecto llamado "hibounce". En mi prueba, admite todas las opciones de ambos, y ocurren simultáneamente. ¡Se ve genial! No soy un gran fan de soluciones como esta, debido al factor de mantenimiento. Cada vez que actualizo jquery.ui, también tendré que actualizar este archivo manualmente.

todos modos, aquí es el resultado combinado (jquery.effects.hibounce.js)

(function($) { 

$.effects.hibounce = function(o) { 
    return this.queue(function() { 
     // Highlight and bounce parts, combined 
     var el = $(this), 
      props = ['position','top','left','backgroundImage', 'backgroundColor', 'opacity'], 
      mode = $.effects.setMode(el, o.options.mode || 'show'), 
      animation = { 
       backgroundColor: el.css('backgroundColor') 
      }; 

     // From highlight 
     if (mode == 'hide') { 
      animation.opacity = 0; 
     } 

     $.effects.save(el, props); 

     // From bounce 
     // Set options 
     var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode 
     var direction = o.options.direction || 'up'; // Default direction 
     var distance = o.options.distance || 20; // Default distance 
     var times = o.options.times || 5; // Default # of times 
     var speed = o.duration || 250; // Default speed per bounce 
     if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE 


     // Adjust 
     $.effects.save(el, props); el.show(); // Save & Show 
     $.effects.createWrapper(el); // Create Wrapper 
     var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; 
     var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; 
     var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true})/3 : el.outerWidth({margin:true})/3); 
     if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift 
     if (mode == 'hide') distance = distance/(times * 2); 
     if (mode != 'hide') times--; 

     // from highlight 
     el 
      .show() 
      .css({ 
       backgroundImage: 'none', 
       backgroundColor: o.options.color || '#ffff99' 
      }) 
      .animate(animation, { 
       queue: false, 
       duration: o.duration * times * 1.3, // cause the hilight to finish just after the bounces (looks best) 
       easing: o.options.easing, 
       complete: function() { 
        (mode == 'hide' && el.hide()); 
        $.effects.restore(el, props); 
        (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter')); 
        (o.callback && o.callback.apply(this, arguments)); 
        el.dequeue(); 
       } 
      }); 

     // Animate bounces 
     if (mode == 'show') { // Show Bounce 
      var animation = {opacity: 1}; 
      animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 
      el.animate(animation, speed/2, o.options.easing); 
      distance = distance/2; 
      times--; 
     }; 
     for (var i = 0; i < times; i++) { // Bounces 
      var animation1 = {}, animation2 = {}; 
      animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 
      animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 
      el.animate(animation1, speed/2, o.options.easing).animate(animation2, speed/2, o.options.easing); 
      distance = (mode == 'hide') ? distance * 2 : distance/2; 
     }; 
     if (mode == 'hide') { // Last Bounce 
      var animation = {opacity: 0}; 
      animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 
      el.animate(animation, speed/2, o.options.easing, function(){ 
       el.hide(); // Hide 
       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 
       if(o.callback) o.callback.apply(this, arguments); // Callback 
      }); 
     } else { 
      var animation1 = {}, animation2 = {}; 
      animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; 
      animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; 
      el.animate(animation1, speed/2, o.options.easing).animate(animation2, speed/2, o.options.easing, function(){ 
       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore 
       if(o.callback) o.callback.apply(this, arguments); // Callback 
      }); 
     }; 
     el.queue('fx', function() { el.dequeue(); }); 
     el.dequeue(); 
    }); 
}; 

})(jQuery); 

Se puede utilizar como cualquier otro efecto ahora:

var el = $("#div1"); 
el.effect("hibounce", {color: "#F00", times: 5}, 100); 
1

Usted podría intentar esto:

var els = $(".errorMsg"); 
setTimeout(function() { 
    els.effect("bounce", {times: 5}, 100); 
}, 1); 
setTimeout(function() { 
    els.effect("highlight", {color: "#ffb0aa"}, 300); 
}, 1); 

Eso debería llamar tanto los efectos más o menos al mismo tiempo, de forma asíncrona.

+0

Mañana daré una oportunidad, cuando regrese al código, si funciona, votaré y marcaré como respuesta. ¡Gracias! –

+2

Dudo que esto funcione mientras falla el método directo. Todavía estás llamando a la función 'efecto' uno por uno. Recuerde que Javascript se ejecuta con un solo subproceso, por lo que ambos se ejecutarán linealmente. – LiraNuna

+1

LiraNuna lo llamó. Las animaciones siguen en cola, y los efectos se ejecutan uno después del otro. Sin embargo, LiraNuna, mientras que javascript puede ser de un solo hilo, es posible ejecutar 2 efectos de una manera que parece ser simultánea. Ciertamente puedes hacerlo usando jquery's animate(), proporcionando {queue: false} en las opciones.Antes de las CPU de subprocesos múltiples/núcleos múltiples, los sistemas operativos utilizaban divisiones de tiempo para ejecutar varios subprocesos. JS no es tan diferente. –

4

jQuery IU efectos cola animaciones, así que escriba su propia versión de una función de rebote/resaltado. Simplemente copie el código fuente de ambos en una sola función, limpie el código, y cada vez que llame animado, asegúrese de tener juntas la lógica de rebote y resaltado.

+0

He considerado esta opción, y puedo recurrir a ella si realmente necesito ambos efectos. Por ahora, estoy contento de tener el código más simple y usar solo 1 de los efectos. Es una lástima que jquery le permita especificar {queue: false} para llamadas a animate(), pero no a effect(). –

11

jQuery UI pondrá en cola los efectos por defecto. Utilice quitar de la cola() para ejecutar de forma simultánea:

var opt = {duration: 7000}; 

    $('#lbl').effect('highlight', opt).dequeue().effect('bounce', opt); 

Demo in JsFiddle

+0

Esto no funciona de la manera que parece. Intente revertir el rebote y resalte y verá que realmente no están ocurriendo simultáneamente. –

+0

Tienes razón @CharlesWood. No funciona cuando 'hightlight' está antes de 'rebote'. He jugado un poco con el violín: otros efectos, como "ciego", "puff" y "pliegue", funcionan bien con resaltar al final. Parece ser un problema con rebote antes de resaltar. No estoy seguro por qué – HoffZ

Cuestiones relacionadas