2010-02-26 6 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 вы используете? –

+0

1.4.2, интерфейс 1.7.2. Итак, последняя стабильность как на момент написания этой статьи. –

ответ

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

Я дам этот снимок завтра, когда вернусь к коду, если он сработает, я проголосую и отметю как ответ. Благодаря! –

+2

Я сомневаюсь, что это сработает, пока метод прямой прямой не сработает. Вы по-прежнему вызываете функцию «эффект» по одному. Помните, что Javascript запускается с одним потоком, так что оба будут выполняться линейно. – LiraNuna

+1

LiraNuna назвал это. Анимации все еще очереди, и эффекты выполняются один за другим. Тем не менее, LiraNuna, в то время как javascript может быть однопоточным, возможно, что 2 эффекта выполняются таким образом, который кажется одновременным. Вы можете сделать это с помощью анимации jquery(), предоставив {queue: false} в параметрах.Перед многопоточными/многоядерными процессорами ОС использовали временную разбивку для запуска нескольких потоков. JS не так уж и отличается. –

4

jQuery UI эффекты анимации очереди, поэтому напишите свою собственную версию функции отскока/выделения. Просто скопируйте исходный код из одной в одну функцию, очистите код, и каждый раз, когда он вызывает анимировать, убедитесь, что в нем есть отскок и выделение логики.

+0

Я рассмотрел этот вариант, и я могу отказаться от него, если мне действительно нужны оба эффекта. На данный момент я доволен, что код проще, и используйте только один из эффектов. Слишком плохо, что jquery позволяет указать {queue: false} для вызовов animate(), но не effect(). –

11

JQuery UI в очередь эффекты по умолчанию. Используйте DEQUEUE() для запуска одновременно:

var opt = {duration: 7000}; 

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

Demo in JsFiddle

+0

Это не работает так, как кажется. Попробуйте обратить вспять отскок и выделить, и вы увидите, что они не происходят одновременно. –

+0

Вы правы @CharlesWood. Это не работает, когда «hightlight» перед «отказом». Я немного поиграл со скрипкой: другие эффекты, такие как «слепой», «слоеный» и «сгиб», хорошо работают с подсветкой. Кажется, это проблема с отказом перед подсветкой. Не уверен, почему – HoffZ