Ответ 1
Думаю, я понял это. Согласно this, анимация css не может применяться к тому же node дважды (даже если у вас есть другая анимация!). Поэтому мне пришлось клонировать node, удалить оригинал и добавить обратно клонированный node.
Я использую 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 дважды, но фактическая анимация вызывается только в первый раз.
Думаю, я понял это. Согласно this, анимация css не может применяться к тому же node дважды (даже если у вас есть другая анимация!). Поэтому мне пришлось клонировать node, удалить оригинал и добавить обратно клонированный node.
Проблема заключается в том, что, хотя вы удаляете и затем повторно применяете анимированный класс, вы делаете это в рамках одной функции блокировки. Когда ваша функция завершается, кажется, что движок рендеринга ничего не изменил.
Одно решение (выбранное вами) - это клонирование элемента и уничтожение оригинала. Это нормально, но если у вас есть привязки к исходному элементу (я думаю), они тоже будут уничтожены.
Другим подходом является удаление анимированного класса из этого элемента, а затем перенос кода, который повторно применяет класс внутри вызова setTimeout() с очень небольшой задержкой, например.
$('#holder').removeClass('shader');
setTimeout(
function(){$('#holder').addClass('shader')}
, 1);
Я изменил ваш jsfiddle, чтобы использовать этот подход: http://jsfiddle.net/HuFBN/7/
Согласно статье 2011 на css-tricks.com, при запуске обновления между удалением и добавлением класса перезапустится анимация. Пример (verbose):
$('#holder').removeClass('shader');
$('#holder').offsetWidth = $('#holder').offsetWidth; // triggers reflow
$('#holder').addClass('shader'); // restarts animation
Вам нужно воссоздать свой элемент.
function resetAnimation(jqNode) {
var clone = jqNode.clone();
jqNode.after( clone );
jqNode.remove();
jqNode[0] = clone[0];
}
Попробуйте использовать это сразу после применения анимации - учитывая, что "e" - ваш анимированный элемент:
e.outerHTML = e.outerHTML;
Вам определенно нужно удалить класс, содержащий анимацию, а затем добавить его снова. Он также должен работать без .offsetWidth
. Это сработало для меня. Так
$('#id').removeClass('animationClass');
$('#id').addClass('animationClass'); // starts animation again
должен сделать трюк.
способ вызвать оплавление:
element.classList.remove("class");
element.scrollBy(0, 0);
element.classList.add("class");
работает в строгом режиме! не требует операции записи для значения только для чтения! не требует совершенно новой функции! одна строка и вперед! :)