Когда возникает необходимость анимации для появляющегося элемента, многие разработчики сразу обращаются к jQuery:
$('.foo').fadeIn(300);
или
$('.foo').fadeOut(300);
Почему выбираем jQuery?
Потому что это просто и удобно. jQuery также предоставляет возможность вызывать callback-функцию после завершения анимации:
$('.foo').fadeIn(300, doSomethingAfterIt);
Это быстро и эффективно. Однако вся анимация, предлагаемая jQuery, реализована на чистом JavaScript, без использования CSS.
Проблема производительности
Хороший frontend-разработчик знает, что для достижения наилучшей производительности анимации должны быть реализованы с использованием CSS. Использование jQuery-функций .hide()
, .show()
, .toggle()
, .fadeIn()
, .slideUp()
не рекомендуется.
CSS Переходы (Transition)
Использование CSS-свойства transition
— это правильный подход. Всё, что нужно сделать, это добавить класс с нужным свойством элементу:
.foo {
opacity: 0;
transition: opacity 300ms;
}
.fade-in {
opacity: 1;
}
$('.foo').addClass('fade-in');
Проблемы при использовании CSS Transition
Проблема 1: Callback-функции после Transition
Для использования callback-функций после завершения перехода можно воспользоваться событием transitionend
:
$('.foo')
.addClass('fade-in')
.one('transitionend', doSomethingAfterIt);
Теперь callback-функции доступны после любой анимации.
Проблема 2: Анимация элемента с display: none
Анимация скрытого элемента – распространенная проблема. Если мы добавим класс с нужными свойствами к такому элементу и используем transition
, ничего не произойдет.
/* исходное состояние элемента */
.foo {
display: none;
opacity: 0;
transition: opacity 300ms;
}
/* желаемый результат */
.foo.fade-in {
display: block;
opacity: 1;
}
Это происходит потому, что элемент не отрисован и не занимает места на экране. Transition для элемента с display: none
не работает.
Метод Reflow
Чтобы добавить анимацию элементу с исходным свойством display: none
, нужно форсировать reflow. Reflow вызывается при изменении размеров элемента, что приводит к перерасчету макета страницы.
Для этого добавим элементу класс со свойством display: block
и вызовем метод, возвращающий размеры элемента. Это заставит браузер обновить элемент и запустить reflow, после чего элемент займёт место на экране и анимация с помощью transition станет возможной.
Пример рабочего кода
var $foo = $('.foo');
$foo
.addClass('block')
.outerWidth(); // Reflow
$foo
.addClass('fade-in')
.one('transitionend', function() {
alert('Animated');
});
.block {
display: block;
}
.fade-in {
opacity: 1;
}
Заключение
Переход от jQuery к CSS-анимациям не только улучшает производительность, но и делает ваш код более современным и гибким. Использование CSS-свойства transition
в сочетании с методами принудительного reflow позволяет легко и эффективно анимировать элементы, которые были скрыты.