2010-02-26 95 views
15

我正在動畫頁面上的一些錯誤/驗證元素。我希望他們能夠反彈並突出顯示,但如果可能的話同時進行。下面是目前我在做什麼:我該如何執行多個同時的jQuery效果?

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

這將導致要素先反彈,然後加以突出,我希望他們同時發生。我知道.animate()可以在選項中指定queue:false,但我不想使用動畫效果,因爲預先構建的效果「反彈」和「高光」正是我想要的效果。

我試圖簡單地鏈接像els.effect().effect()這樣的電話,並且不起作用。我也嘗試將queue:false放入我傳入的選項對象中,但這不起作用。

+0

您正在使用什麼版本的jQuery? – 2010-02-26 21:05:35

+0

1.4.2,UI 1.7.2。所以,在撰寫本文時,兩者都是最新的穩定版本。 – 2010-02-26 22:17:19

回答

8

好吧,所以這是一個非常自定義的解決方案,結合了反彈和高光效果。我更願意看到某種jQuery支持更容易地組合這些,指定{queue:false},但我不認爲這很簡單。

我所做的是將jquery.effects.bounce.js和jquery.effects.highlight.js(來自jquery-ui-1.8rc3),並將兩者的代碼結合爲DaveS建議的,以創建一個新的效果名爲「hibounce」。在我的測試中,它支持兩者的所有選項,並且它們同時發生。看起來不錯!我不是一個巨大的這樣的解決方案的粉絲,但由於維護因素。任何時候我升級jquery.ui,我將不得不手動更新這個文件。

無論如何,這裏是組合的結果(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); 

它可以像現在的任何其它效果一起使用:

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

你可以試試這個:

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

這應該通話雙方在大致相同的時間的影響,異步。

+0

明天當我回到代碼時,我會給出這個鏡頭,如果它有效,我會投票並標記爲答案。謝謝! – 2010-02-28 22:02:06

+2

我懷疑這將工作,而直接的方法失敗。你仍然在逐一調用「效果」函數。記得Javascript是單線程運行的,所以兩者都要線性執行。 – LiraNuna 2010-03-01 07:54:08

+1

LiraNuna稱它。動畫仍然排隊,並且效果一個接一個地執行。然而,LiraNuna,雖然javascript可能是單線程的,但可能有兩種效果以似乎是同時執行的方式執行。你當然可以使用jquery的animate(),通過在選項中提供{queue:false}。在多線程/多核CPU之前,操作系統使用時間分片來運行多個線程。 JS並非完全不同。 – 2010-03-01 18:37:26

4

jQuery UI的效果隊列動畫,所以寫你自己的版本的反彈/高光功能。只需將兩者的源代碼複製到一個函數中,清理代碼,並且每次調用動畫時,都要確保將彈跳和高亮邏輯放在一起。

+0

我已經考慮過這個選項,如果我真的需要這兩個效果,我可能會回頭。現在,我滿足於讓代碼更簡單,只使用1個效果。 jquery允許你爲animate()的調用指定{queue:false},但不會影響(),這太糟糕了。 – 2010-03-01 18:39:13

11

jQuery的用戶界面將排隊的影響默認。使用出隊()同時運行:

var opt = {duration: 7000}; 

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

Demo in JsFiddle

+0

這實際上並不像它看起來那樣工作。嘗試顛倒反彈並突出顯示,你會發現它們並不是同時發生的。 – 2014-01-22 21:16:03

+0

你是對的@CharlesWood。 'hightlight'在'反彈'之前不起作用。我用小提琴演奏了一下:其他效果,比如「盲」,「泡芙」和「摺疊」,與最後的高光相配。似乎是突出之前彈跳的問題。不知道爲什麼 – HoffZ 2014-01-23 11:21:12

相關問題