2010-02-26 97 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

相关问题