Переход между страницами на основе Ajax со вставляемой анимацией содержимого, запускаемой с помощью навигации с боковыми вкладками.
В последнее время мы экспериментировали с анимацией на основе CSS, которая заменяет обновление веб-страницы, в то время как содержимое обновляется с помощью ajax. Сегодняшний самородок основан на той же идее, но с другим исполнением: на этот раз простой эффект наведения превращается в полосу загрузки, которая, наконец, расширяется новым содержанием!
Иконки из библиотеки nucleoapp.com
Создание структуры
Структура html состоит из элемента .cd-main
, обертывающего содержимое страницы, .cd-side-navigation
, содержащей боковую навигацию, и панели #cd-loading-bar
для создания анимации панели загрузки.
<nav class="cd-side-navigation">
<ul>
<li>
<a href="index.html" class="selected" data-menu="index">
<svg><!-- svg content here --></svg>
Intro
</a>
</li>
<li>
<!-- ... -->
</li>
<!-- other list items here -->
</ul>
</nav> <!-- .cd-dashboard -->
<main class="cd-main">
<section class="cd-section index visible">
<header>
<div class="cd-title">
<h2>Animated Page Transition #2</h2>
<span>Some text here</span>
</div>
<a href="#index-content" class="cd-scroll">Scroll Down</a>
</header>
<div class="cd-content" id="index-content">
<!-- content here -->
</div> <!-- .cd-content -->
</section> <!-- .cd-section -->
</main> <!-- .cd-main -->
<div id="cd-loading-bar" data-scale="1" class="index"></div> <!-- lateral loading bar -->
Добавление стиля
.cd-side-navigation
находится в фиксированном положении, с высотой: 100% и переполнением: скрыто, в то время как его дочерний элемент <ul>
имеет overflow-y: auto
(так что вы можете прокручивать внутри него, если навигация выше чем окно просмотра).
Чтобы создать строку, видимую при наведении курсора на каждый элемент навигации, мы использовали псевдоэлементы a :: after
. Они находятся в абсолютном положении, имеют ширину: 4 пикселя, верхнюю границу: 0 и правую сторону: -4 пикселя.
Одно примечание:
Мы присвоили ширину: calc (100% - 4px)
каждому элементу элемента списка, чтобы иметь возможность размещать элементы a ::after
внутри .cd-side-navigation
(поскольку у него есть overflow: hidden
).
.cd-side-navigation {
position: fixed;
z-index: 3;
top: 0;
left: 0;
height: 100vh;
width: 94px;
overflow: hidden;
}
.cd-side-navigation ul {
height: 100%;
overflow-y: auto;
}
.cd-side-navigation::before {
/* background color of the side navigation */
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: calc(100% - 4px);
background-color: #131519;
}
.cd-side-navigation li {
width: calc(100% - 4px);
}
.cd-side-navigation a {
display: block;
position: relative;
}
.cd-side-navigation a::after {
/* 4px line to the right of the item - visible on hover */
content: '';
position: absolute;
top: 0;
right: -4px;
height: 100%;
width: 4px;
background-color: #83b0b9;
opacity: 0;
}
.no-touch .cd-side-navigation a:hover::after {
opacity: 1;
}
Когда пользователь выбирает новый элемент на боковой панели навигации, создается новый элемент .cd-section
, который вставляется в DOM (более подробную информацию можно найти в разделе «Обработка событий»).
По умолчанию этот новый элемент .cd-section
переводится влево, за пределы области просмотра (translateX (-100%)
). Затем он перемещается обратно в область просмотра (с использованием класса .visible
) для замены старого содержимого.
.cd-section {
position: absolute;
z-index: 1;
top: 0;
left: 0;
height: 100%;
width: 100%;
transform: translateX(-100%);
transition: transform 0s 0.5s;
}
.cd-section.visible {
/* this is the visible/selected section */
position: relative;
z-index: 2;
transform: translateX(0);
transition: transform 0.5s 0s;
}
Обработка событий
Файл index.html содержит только «Вступление». Для каждого элемента навигации (services.html, contact.html, ..) был создан отдельный html-файл с точно такой же структурой, но с разным содержанием .cd-section
.
Когда пользователь щелкает один из элементов в боковой навигации, выполняется функция triggerAnimation ()
. Эта функция запускает анимацию панели загрузки (функция loadingBarAnimation ()
) и загружает новый контент (функция loadNewContent ()
).
Для анимации панели загрузки мы использовали velocityjs.org: в начале анимации панель #cd-loading-bar
помещается прямо рядом с выбранным элементом навигации (его высота равна высоте элемента списка). Затем его значение scaleY
анимируется для создания эффекта загрузки.
function loadingBarAnimation() {
//loadingBar is the #cd-loading-bar element
//scaleY is the loadingBar actual scale value
var scaleMax = loadingBar.data('scale'); //this is the scaleY value to cover the entire window height (100% loaded)
if( scaleY + 1 < scaleMax) {
newScaleValue = scaleY + 1;
}
// ...
loadingBar.velocity({
scaleY: newScaleValue
}, 100, loadingBarAnimation
);
}
Когда выбирается новая страница, создается новый элемент .cd-section
, который вставляется в DOM. Затем функция load ()
используется для загрузки нового содержимого (мы использовали атрибут меню данных, назначенный элементам списка навигации, чтобы определить, какое содержимое файла будет загружено). После загрузки нового HTML анимация полосы загрузки завершается, старое содержимое заменяется новым, а новая страница добавляется в window.history (с помощью метода pushState ()
).
function loadNewContent(newSection) {
//create a new section element and insert it into the DOM (newSection is the data-menu of the selected navigation item)
var section = $('').appendTo(mainContent);
//load the new content from the proper html file
section.load(newSection+'.html .cd-section > *', function(event){
loadingBar.velocity({
scaleY: scaleMax //this is the scaleY value to cover the entire window height (100% loaded)
}, 400, function(){
//add the .visible class to the new section element -> it will cover the old one
section.addClass('visible');
var url = newSection+'.html';
if(url!=window.location){
//add the new page to the window.history
window.history.pushState({path: url},'',url);
}
// ...
}
);
});
}
Чтобы вызвать тот же эффект анимации, когда пользователь нажимает кнопку возврата в браузере, мы прослушиваем событие popstate
и выполняем функцию triggerAnimation ()
, когда она запускается.
Надеюсь, вам понравилось!
Ссылка на автора - twitter.com/romano_cla !