Анимация с поддержкой CSS, которая заменяет обновление страницы при обновлении контента с помощью jQuery.
Мы играли вокруг идеи замены обновления веб-страницы анимацией, которая имеет место, когда новый контент страницы загружается с помощью Ajax. Мы использовали метод pushState для управления историей браузера.
Создание структуры
Структура HTML состоит из элемента <main>
, обертывающего содержимое страницы, слоя div.cd-cover-layer
, который используется для создания слоя, охватывающего контент во время перехода страницы, и div.cd-loading-bar
для создания анимации загрузочной панели.
<main>
<div class="cd-index cd-main-content">
<div>
<h1>Page Transition</h1>
<!-- your content here -->
</div>
</div>
</main>
<div class="cd-cover-layer"></div> <!-- this is the cover layer -->
<div class="cd-loading-bar"></div> <!-- this is the loading bar -->
Добавление стиля
Мы использовали body::before
и body::after
псевдоэлементов, чтобы создать 2 блока, которые покрывают содержимое страницы во время перехода страницы: эти элементы находятся в фиксированном положении, высота которых равна 50vh, а ширина равна 100% видовой экран. По умолчанию они скрыты за пределами области просмотра, используя свойство преобразования CSS (translateY (-100%)
/ translateY (100%)
). Когда пользователь запускает переход страницы, эти элементы перемещаются обратно в окно просмотра (используя класс .page-is-changing
, добавленный к элементу <body>
).
Вот быстрая анимация, которая показывает начальную позицию body::before
, body::after
и элементы div.cd-loading-bar
(gif, созданный в After Effects):
body::after, body::before {
/* these are the 2 half blocks which cover the content once the animation is triggered */
height: 50vh;
width: 100%;
position: fixed;
left: 0;
}
body::before {
top: 0;
transform: translateY(-100%);
}
body::after {
bottom: 0;
transform: translateY(100%);
}
body.page-is-changing::after, body.page-is-changing::before {
transform: translateY(0);
}
Эффект затухания содержимого страницы во время перехода страницы достигается за счет увеличения непрозрачности слоя div.cd-cover-layer
. Он охватывает весь элемент .cd-main-content
, имеет тот же фоновый цвет, а его непрозрачность анимируется от 0 до 1, когда класс .page-is-changing
присваивается <body>
.
Анимация индикатора выполнения создается с использованием .cd-loading-bar::before
pseudo-element
: по умолчанию он уменьшен (scaleX (0) и origin-origin: left center), тогда как он масштабируется, когда происходит переход страницы (scaleX (1)).
.cd-loading-bar {
/* this is the loading bar - visible while switching from one page to the following one */
position: fixed;
height: 2px;
width: 90%;
}
.cd-loading-bar::before {
/* this is the progress bar inside the loading bar */
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
transform: scaleX(0);
transform-origin: left center;
}
.page-is-changing .cd-loading-bar::before {
transform: scaleX(1);
}.cd-loading-bar {
/* this is the loading bar - visible while switching from one page to the following one */
position: fixed;
height: 2px;
width: 90%;
}
.cd-loading-bar::before {
/* this is the progress bar inside the loading bar */
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
transform: scaleX(0);
transform-origin: left center;
}
.page-is-changing .cd-loading-bar::before {
transform: scaleX(1);
}
Плавная анимация достигается с помощью переходов CSS. Мы использовали другое значение transition-delay
для каждого анимированного элемента, чтобы выполнить различные анимации в правильном порядке.
Обработка событий
Мы использовали data-type="page-transition"
для таргетинга ссылок, запускающих действие. Когда обнаружено событие клика, выполняется функция changePage()
:
$('main').on('click', '[data-type="page-transition"]', function(event){
event.preventDefault();
//detect which page has been selected
var newPage = $(this).attr('href');
//if the page is not animating - trigger animation
if( !isAnimating ) changePage(newPage, true);
});
Эта функция запускает анимацию страницы и загружает новый контент (loadNewContent()
):
function changePage(url, bool) {
isAnimating = true;
// trigger page animation
$('body').addClass('page-is-changing');
//...
loadNewContent(url, bool);
//...
}
Когда новый контент загружен, он заменяет старое содержимое внутри элемента <main>
, класс .page-is-changing
удаляется из тела (чтобы отменить анимацию страницы), а новая загруженная страница добавляется в window.history (используя метод pushState()
).
function loadNewContent(url, bool) {
var newSectionName = 'cd-'+url.replace('.html', ''),
section = $('<div class="cd-main-content '+newSectionName+'"></div>');
section.load(url+' .cd-main-content > *', function(event){
// load new content and replace <main> content with the new one
$('main').html(section);
//...
$('body').removeClass('page-is-changing');
//...
if(url != window.location){
//add the new page to the window.history
window.history.pushState({path: url},'',url);
}
});
}
Чтобы вызвать ту же анимацию страницы, когда пользователь нажимает кнопку «Назад» браузера, мы слушаем событие popstate
и выполняем функцию changePage()
при ее запуске:
$(window).on('popstate', function() {
var newPageArray = location.pathname.split('/'),
//this is the url of the page to be loaded
newPage = newPageArray[newPageArray.length - 1];
if( !isAnimating ) changePage(newPage);
});
Вы можете узнать больше о событии popstate и о том, как браузеры обрабатывают его здесь.
Примечание.
Мы выполнили функцию basic load()
для загрузки нового контента, но вы можете заменить его, например, вызовом $ .ajax
для обработки ошибок и т. д.