2010-02-26 8 views
15

Ich animiere einige Fehler/Validierungselemente auf einer Seite. Ich möchte, dass sie hüpfen und hervorgehoben werden, aber gleichzeitig wenn möglich. Hier ist, was ich momentan mache:Wie kann ich mehrere simultane Jquery-Effekte ausführen?

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

Dies bewirkt, dass die Elemente zum ersten bounce, und dann hervorgehoben werden, und ich würde sie gleichzeitig auftreten mag. Ich weiß, dass mit .animate() können Sie queue:false in den Optionen angeben, aber ich möchte nicht animieren, weil die vorgefertigten Effekte "Bounce" und "Highlight" genau das sind, was ich will.

Ich habe versucht, einfach die Anrufe wie els.effect().effect() verketten, und das funktioniert nicht. Ich habe auch versucht, queue:false in das Optionsobjekt zu setzen, das ich übergebe, und das funktioniert nicht.

+0

Welche Version von jQuery verwenden Sie? –

+0

1.4.2, UI 1.7.2. Also, spätestes stabiles von beiden zur Zeit dieses Schreibens. –

Antwort

8

Ok, das ist eine sehr individuelle Lösung, die Bounce- und Highlight-Effekte kombiniert. Ich würde lieber eine Art von jQuery-Unterstützung sehen, um diese leichter zu kombinieren, indem ich {queue: false} spezifiziere, aber ich denke nicht, dass es so einfach ist.

Was ich getan habe, war die jquery.effects.bounce.js und jquery.effects.highlight.js (von jquery-ui-1.8rc3), und kombinieren Sie den Code der beiden wie DaveS vorgeschlagen, um ein neues zu erstellen Effekt namens "hibounce". In meinen Tests unterstützt es alle Optionen von beiden und sie treten gleichzeitig auf. Das sieht großartig aus! Ich bin kein riesiger Fan von Lösungen wie diesem, aber wegen des Wartungsfaktors. Jedes Mal, wenn ich jquery.ui aktualisiere, muss ich diese Datei auch manuell aktualisieren.

, jedenfalls hier ist das kombinierte Ergebnis (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); 

Es kann nun wie jede andere Wirkung verwendet werden:

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

Sie konnten dieses versuchen:

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

, das an beiden die Effekte in etwa zur gleichen Zeit nennen sollte, asynchron.

+0

Ich gebe morgen eine Aufnahme, wenn ich wieder im Code bin, wenn es funktioniert, werde ich abstimmen und als Antwort markieren. Vielen Dank! –

+2

Ich bezweifle, dass dies funktioniert, während die direkte Methode fehlschlägt. Sie rufen immer noch die Funktion "Effekt" nacheinander auf. Denken Sie daran, dass Javascript in single threaded ausgeführt wird, so dass beide linear ausgeführt werden. – LiraNuna

+1

LiraNuna nannte es. Die Animationen stehen immer noch in der Warteschlange, und die Effekte werden nacheinander ausgeführt. LiraNuna, während JavaScript Single-Threaded sein kann, ist es möglich, dass zwei Effekte auf eine Weise ausgeführt werden, die simultan erscheint. Sie können dies natürlich mit jquery's animate() tun, indem Sie {queue: false} in den Optionen angeben.Vor Multi-Threaded-/Multicore-CPUs verwendeten Betriebssysteme Time-Slicing, um mehrere Threads auszuführen. JS ist nicht so anders. –

4

jQuery UI die Effekte Warteschlange Animationen, so schreiben Sie Ihre eigene Version einer Bounce/Highlight-Funktion. Kopieren Sie einfach den Quellcode aus beiden in eine einzelne Funktion, bereinigen Sie den Code, und stellen Sie bei jedem Aufruf von animate sicher, dass die Bounce- und Highlight-Logik darin enthalten ist.

+0

Ich habe diese Option in Betracht gezogen, und ich kann darauf zurückgreifen, wenn ich wirklich beide Effekte brauche. Fürs Erste bin ich zufrieden, den Code einfacher zu haben und nur einen der Effekte zu verwenden. Es ist schade, dass jquery es erlaubt, {queue: false} für Aufrufe von animate(), aber nicht effect() anzugeben. –

11

jQuery UI wird die Auswirkungen Warteschlange standardmäßig. Verwenden Sie dequeue() gleichzeitig ausgeführt werden:

var opt = {duration: 7000}; 

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

Demo in JsFiddle

+0

Das funktioniert nicht so, wie es aussieht. Versuchen Sie, Bounce und Highlight umzukehren, und Sie werden sehen, dass sie nicht wirklich gleichzeitig auftreten. –

+0

Sie haben Recht @CharlesWood. Es funktioniert nicht, wenn "Hightlight" vor "Bounce" steht. Ich habe ein bisschen mit der Geige herumgespielt: Andere Effekte, wie "blind", "puff" und "fold", funktionieren ok mit highlight last. Scheint ein Problem mit dem Bounce vor dem Highlight zu sein. Nicht sicher warum – HoffZ