CSS3 animation-fill-mode polyfill
Введение
Предположим, что a div
анимируется от opacity:0;
до opacity:1;
, и я хочу сохранить opacity:1;
после окончания анимации.
Что делает animation-fill-mode:forwards;
.
@keyframes myAnimation {
from { opacity:0; }
to { opacity:1; }
}
div {
opacity:0;
animation-name:myAnimation;
animation-delay:1s;
animation-duration:2s;
animation-fill-mode:forwards;
}
<div>just a test</div>
Запустить его на jsFiddle
- Примечание 1: я не включил префиксы поставщика для упрощения
- Примечание 2: это просто пример, пожалуйста, не отвечайте "просто используйте функцию jQuery fadeIn" и т.д.
Некоторые вещи, чтобы знать
В этом ответе я читал, что animation-fill-mode
поддерживается браузерами Chrome 16+, Safari 4+, Firefox 5 +.
Только animation
поддерживается Chrome 1+ и Opera. Таким образом, общий тест с Modernizr может возвращать положительный результат, даже если fill-mode
не поддерживается.
Чтобы настроить таргетинг на animation-fill-mode
, я добавил новый тест на Modernizr:
Modernizr.addTest('animation-fill-mode',function(){
return Modernizr.testAllProps('animationFillMode');
});
Теперь у меня есть класс .no-animation-fill-mode
для CSS и Modernizr.animationFillMode
для JavaScript.
Я также читал из спецификации анимации CSS3, которые:
анимация, указанная в таблице стилей документа, начнется с загрузка документа
Наконец, вопрос (ы)
Можно ли запустить простую функцию jQuery с точным количеством секунд окончания анимации
$(document).ready(function(){
if(!Modernizr.animation){
$('div').delay(1000).fadeIn(2000);
}else if(!Modernizr.animationFillMode){
$('div').delay(3000).show();
}
});
И в CSS:
.no-animation-fill-mode div {
animation-iteration-count:1;
}
/* or just animation:myAnimation 2s 1s 1; for everyone */
Или существует ли какой-либо известный polyfill для animation-fill-mode
?
Кроме того, что произойдет, если я использую сокращенный синтаксис
animation:myAnimation 2s 1s forwards;
в браузерах, поддерживающих animation
, но не animation-fill-mode
?
Спасибо большое!
Ответы
Ответ 1
Если бы это был я, я бы попробовал выбрать более простой вариант - если это возможно. Я бы понизил мою реализацию, чтобы использовать только то, что принято. Позже, когда функция более широко поддерживается, я тогда думаю о ее реализации. Я редко рассматриваю возможность использования функции, которая имеет This is an experimental technology
широковещательную рассылку на страницах документации, - но тогда, возможно, меня следует считать скучным:)
В вашем примере вы можете достичь того же результата, что и animation-fill-mode:forwards
, сначала определяя конечное состояние своего элемента и используя цепочку анимации (если требуется задержка перед действием):
@keyframes waitandhide {
from { opacity:0; }
to { opacity:0; }
}
@keyframes show {
from { opacity:0; }
to { opacity:1; }
}
div {
opacity:1;
animation: waitandhide 2s 0s, show 2s 2s;
}
<div>just a test</div>
http://jsfiddle.net/RMJ8s/1/
Теперь возможно, что более медленные браузеры могут высвечивать ваши начальные состояния элементов, прежде чем снова скрывать их. Но, по моему опыту, я видел это только на очень старых машинах и на страницах с огромным количеством CSS для рендеринга.
Очевидно, что выше это раздувает ваш css немного больше (поскольку вам нужно дублировать стили), и это будет сложнее при работе со сложными анимациями. Однако:
- Он должен работать практически для любой анимационной ситуации.
- Это позволит избежать необходимости в JavaScript (за исключением $(). fadeIn fallback).
- Он будет работать на всех браузерах, поддерживающих анимацию css.
- Вы не рискуете быть несинхронизированными JS и CSS.
Что касается использования коротких форм, было бы лучше не делать, если вы хотите как можно более широко использовать браузерную совместимость. Однако, как показано в моих примерах выше, я выбрал использование коротких форм, потому что они имеют большую ясность, и я понимаю, что не хочу писать (или читать) длинные версии все время. По этой причине я бы рекомендовал использовать меньше, чтобы сгенерировать ваш css:
http://lesscss.org/
http://radiatingstar.com/css-keyframes-animations-with-less
Ответ 2
Я не знаю ни одного polyfill...
Но я бы сказал, что вы действительно должны использовать свой собственный тест Modernizr, а для браузера, который не поддерживает режим анимации, вы должны использовать событие animationEnd
, чтобы вызвать ваш обратный вызов и установить непрозрачность в 1 (или удалить класс).
Смотрите: События перехода CSS3
Что касается сокращенной нотации, IE < 10 не поддерживает свойство анимации-заливки, и я уверен, что он сломал бы всю декларацию.
Ответ 3
FYI, вот как я реализую ответ pebbl (который является очень умным ответом) в наши дни. Мне нужно Modernizr определение css-анимации.
Предположим, что я хочу скользить и исчезать этот div:
<div class="target">Some stuff</div>
прежде всего, я записываю анимацию с префиксами поставщика
@keyframes byebye {
0% { height:100px; opacity:1; }
100% { opacity:0; height:0; }
}
то новый класс
.target-animation {
height:0; opacity:0; // same as "100%" state
animation:byebye 750ms 1;
}
переход на javascript:
// $('.whatever').on('click',function(){ ...
if(Modernizr.cssanimations)
// css animations are supported!
$('.target').addClass('target-animation');
else
// i hate you IE
$('.target').animate({height:0,opacity:0},750);
Если вам нужно вызвать мультипликацию несколько раз, просто удалите класс с помощью javascript, как описано здесь:
// if(Modernizr.cssanimations) ...
$('target').addClass('target-animation').on('webkitAnimationEnd oAnimationEnd oanimationend animationend msAnimationEnd',function(){
$(this).removeClass('target-animation')
// don't forget to .hide() if needed
});
// ... else