Анимация CSS не перезапускается при сбросе класса

Я использую CSS-шейдер + анимация. Мой класс шейдеров определяется следующим образом:

.shader{
-webkit-filter :custom(url(v.vs) mix(url(f.fs) multiply destination-over), 200 200);
-webkit-animation-name: test;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1
}

Я пытаюсь установить/сбросить стили (шейдер + анимация) динамически с помощью jquery через $('#holder').addClass('shader'); и $('#holder').removeClass('shader');

Однако странная вещь заключается в том, что когда я сбрасываю класс (например, вызываю addClass после removeClass), только шейдер повторно применяется, а анимация - нет (я подключил событие AnimationStart, чтобы увидеть, когда моя анимация запускается). Кто-нибудь знает, почему это так и как я могу это решить?

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

Ответ 1

Думаю, я понял это. Согласно this, анимация css не может применяться к тому же node дважды (даже если у вас есть другая анимация!). Поэтому мне пришлось клонировать node, удалить оригинал и добавить обратно клонированный node.

Ответ 2

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

Одно решение (выбранное вами) - это клонирование элемента и уничтожение оригинала. Это нормально, но если у вас есть привязки к исходному элементу (я думаю), они тоже будут уничтожены.

Другим подходом является удаление анимированного класса из этого элемента, а затем перенос кода, который повторно применяет класс внутри вызова setTimeout() с очень небольшой задержкой, например.

$('#holder').removeClass('shader');
setTimeout(
    function(){$('#holder').addClass('shader')}
    , 1);

Я изменил ваш jsfiddle, чтобы использовать этот подход: http://jsfiddle.net/HuFBN/7/

Ответ 4

Вам нужно воссоздать свой элемент.

function resetAnimation(jqNode) {
   var clone = jqNode.clone();
   jqNode.after( clone );
   jqNode.remove();
   jqNode[0] = clone[0];
}

Ответ 5

Попробуйте использовать это сразу после применения анимации - учитывая, что "e" - ваш анимированный элемент:

e.outerHTML = e.outerHTML;

Ответ 6

Вам определенно нужно удалить класс, содержащий анимацию, а затем добавить его снова. Он также должен работать без .offsetWidth. Это сработало для меня. Так

$('#id').removeClass('animationClass');
$('#id').addClass('animationClass'); // starts animation again

должен сделать трюк.

Ответ 7

способ вызвать оплавление:

  element.classList.remove("class");
  element.scrollBy(0, 0);
  element.classList.add("class");

работает в строгом режиме! не требует операции записи для значения только для чтения! не требует совершенно новой функции! одна строка и вперед! :)