2011-02-09 2 views
10

У меня есть несколько анимаций на одном объекте, и мне нужно остановить определенную анимацию, а не все из них. Это не похоже на метод .stop().Остановка отдельных анимаций jQuery

Например, при одновременной анимации непрозрачности и ширины может потребоваться отменить анимацию непрозрачности, все еще заполняя анимацию ширины. Казалось бы, это невозможно, но я надеюсь, что кто-то знает трюк или вызов API, который мне не хватает.

Примечание: Я не говорю о анимации в очереди, я ищу, чтобы оживить несколько атрибутов одновременно с возможностью остановить некоторые из этих атрибутов анимации после того, как они уже начали

+0

я бы подумал, что будет путь, используя пользовательские именованные очереди, но это не похоже на '.stop()' метод может предназначаться для конкретной очереди (насколько я могу расскажите в любом случае). – user113716

+0

На данный момент я сделал запрос на добавление этой функции http://bugs.jquery.com/ticket/8227 – slifty

+0

Каковы критерии остановки анимации? Это основано на действии пользователя? – Jeff

ответ

8

Ненавижу быть парнем, который отвечает на его собственный вопрос (большое спасибо за подробные ответы и вложил в него мозговую силу!), Но я нашел прямой ответ. По-видимому, существует параметр для метода .animate(), называемого «queue», который по умолчанию имеет значение true, но вы можете установить значение false, чтобы ваша анимация произошла немедленно.

Это означает, что, установив очередь в false, вы можете запускать несколько анимаций, используя отдельные вызовы, не дожидаясь окончания предыдущего. Еще лучше, если вы попытаетесь запустить анимацию для свойства, которое уже анимировано, второе будет переопределять первое. Это означает, что вы можете остановить анимацию свойства, просто «оживляя» ее текущее значение с длительностью 0, используя очередь «false».

Пример:

$myElement = $("#animateElement"); 
$myElement.animate({width: 500}, {duration: 5000}); 
$myElement.animate({height: 500}, {duration: 5000, queue: false}); 
// ... Wait 2 seconds ... 
$myElement.animate({width: $myElement.width()}, {duration: 0, queue: false}); 

Another option был предложен милостивый Jquery вкладчиком, кто откликнулся на просьбу моего улучшения. Это позволяет использовать функцию шага в анимации (функции шагов вызывается в каждой точке анимации, и вы можете управлять параметрами анимации на основе любых критериев, которые вы хотите). Хотя это также могло решить проблему, я чувствовал, что это намного более грязно, чем опция «queue: false».

3

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

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

То есть,

$(element).animate(aThing, aTime); 
      .animate(anotherThing, anotherTime); 

не собирается работать параллельно. aThing завершится в ATIME, а затем anotherThing продолжительностью anotherTime.

Таким образом, вы можете выполнить только несколько изменений, имея их в одной и той же функции:

$(element).animate({aThing: aValue, anotherThing: anotherValue}, aTime); 

Вот краткое объяснение анатомии, как анимационные функции обрабатываются в JQuery.

Объект таймера присваивается элементу для продолжительности анимации:

function t(gotoEnd) { 
    return self.step(gotoEnd); 
} 

t.elem = this.elem; 
jQuery.timers.push(t); 

При вызове функции останова, он удаляет таймер из таймеров:

// go in reverse order so anything added to the queue during the loop is ignored 
for (var i = timers.length - 1; i >= 0; i--) { 
    if (timers[i].elem === this) { 
     if (gotoEnd) { 
      // force the next step to be the last 
      timers[i](true); 
     } 

     timers.splice(i, 1); 
    } 
} 

Итак, это не способ удалить определенное свойство функции анимации, так как сам таймер убит.


Единственный способ, которым я мог думать о выполнении этого было бы следить за временем начала и продолжительность, повторно enqueuing анимации и остановить текущую.

var start = $.now(); 
var duration = 5000; 

$(element).animate({opacity: '0.5', width: '500px'}, duration); 

...

var remaining = duration - ($.now() - start); 
$(element).animate({opacity: '0.5', remaining) 
      .stop(); 
+0

Большое спасибо за ответ! Возможно, я не совсем понимаю, но похоже, что этот код вызовет анимацию ширины продолжительностью 5 секунд, после чего начнется анимация непрозрачности. Мне нужно иметь возможность одновременно запускать анимацию ширины и непрозрачности (т. Е. Изменяются как ширина, так и непрозрачность), с возможностью остановки одного или другого до завершения без остановки обоих. – slifty

+0

Хорошо, я пересмотрел свой ответ сейчас, когда у меня есть лучшее понимание вашего вопроса:). –

+0

Привет, Ян. Я просто хотел поблагодарить вас за такой подробный ответ. Я смог найти прямое решение, которое не требует какого-либо отслеживания, поэтому, к сожалению, я не могу дать вам ответный тег :(Надеюсь, вы сможете использовать это решение хотя бы однажды! – slifty

1

Вместо одной анимации, вы можете разбить его на несколько более мелких анимации (т.е. анимировать непрозрачность от 0-20%, затем анимировать от 20-40%, то 40-60% и т. Д.), А вместо .stop() - в анимации вы просто не запускаете ее снова?

0

Я использую плагин цикла jQuery для анимации дюжины слайд-шоу на одной странице с использованием различных типов анимации (салфетки, тасования, масштабирование и т. Д.). то у меня был собственный крошечный скрипт слегка выцветает изображения, как вы парили над каждым слайд-шоу:

# This code stops all current animations on an element 

$(".box img").hover(
    function(){ 
     $(this).stop().fadeTo("slow",0.7); 
    }, 
    function(){ 
     $(this).stop().fadeTo("fast",1); 
    } 
); 

Проблема была функция .stop() также остановить плагин цикла в нем отслеживающей - мои салфетки, перемешивает и масштабирование останавливали внезапно на полпути через их анимацию, оставляя страницу сломанной и выведенной из положения. Решение было реализовать очереди «ложь» идея:

# This code suited me better - it leaves the other running animations untouched 

$(".box img").hover(
    function(){ 
     $(this).animate({opacity: 0.7}, {duration: 1000, queue: false}); 
    }, 
    function(){ 
     $(this).animate({opacity: 1}, {duration: 250, queue: false}); 
    } 
); 
1

ОБНОВЛЕНИЕ 2013

На JQuery 1.7 вы можете использовать .animate() с именем очереди, и использовать .stop(queuename) остановить только те анимации в очередь.


http://api.jquery.com/stop/

Смежные вопросы