Подтвердить что ты не робот

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?

Спасибо большое!

4b9b3361

Ответ 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