Одностраничные приложения позволяют обновлять определенную часть веб-страницы путем маршрутизации любого содержимого, хранящегося в отдельном файле .html. При этом вы не перезагружаете свою главную страницу.
AngularJS предоставляет модуль с именем ngRoute именно для этой цели.
Еще один полезный модуль AngularJS — это ngAnimate, который позволяет легко анимировать с помощью определенных классов CSS.
В этом уроке я постараюсь подробно объяснить каждый шаг, хотя вам все еще нужны базовые знания AngularJS, чтобы иметь возможность следовать им.
Начиная с главной страницы
Базовая структура
Этот файл index.html станет нашей главной страницей, где у нас есть как фиксированный, так и маршрутизированный контент.
Я начну с базового HTML-документа и style.css все необходимые библиотеки вместе с нашей пользовательской style.css стилей с именем style.css и файлом JavaScript angularApp.js .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
<html>
<head>
<link href=»style.css» rel=»stylesheet»>
</head>
<body>
<script src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-route.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-animate.js»></script>
<script src=»angularApp.js»></script>
</body>
</html>
|
Теперь я добавляю два DIV с именами идентификаторов fixedContent и routedContent внутри mainWrapper DIV.
routedContent также routedContent в другой DIV- routedContent именем wrapper . Это связано с тем, что значение routedContent должно быть абсолютным относительно родительского DIV из-за того факта, что во время анимации маршрутизации два разных фрагмента контента конфликтуют друг с другом.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<html>
<head>
<link href=»style.css» rel=»stylesheet»>
</head>
<body>
<div id=»mainWrapper»>
<div id=»fixedContent»></div>
<div id=»wrapper»>
<div id=»routedContent» ng-view></div>
</div>
</div>
<script src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-route.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-animate.js»></script>
<script src=»angularApp.js»></script>
</body>
</html>
|
Как следует из имен идентификаторов, fixedContent будет статическим содержимым нашей главной страницы, а routedContent будет динамически изменяться при взаимодействии с пользователем.
Чтобы определить приложение Angular в нашем HTML-файле, нам нужно использовать директиву ng-app . Поскольку вся страница будет приложением Angular, нам нужно назначить эту директиву mainWrapper DIV.
Нам также нужна директива ng-view , которая сообщает DIV, что она назначена для отображения содержимого перенаправленной страницы.
Теперь наш файл index.html выглядит так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<html>
<head>
<link href=»style.css» rel=»stylesheet»>
</head>
<body>
<div id=»mainWrapper» ng-app=»mainApp»>
<div id=»fixedContent»></div>
<div id=»wrapper»>
<div id=»routedContent» ng-view></div>
</div>
</div>
<script src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-route.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-animate.js»></script>
<script src=»angularApp.js»></script>
</body>
</html>
|
Меню навигации
Нам нужно навигационное меню, чтобы направлять различные фрагменты контента в ng-view .
Мы собираемся использовать ul и элементы для создания простого горизонтального меню. Ниже вы можете увидеть фрагмент HTML для структуры меню.
|
1
2
3
4
5
6
7
8
|
<div id=»fixedContent»>
<ul>
<a href=»#page1″>Page1</a>
<a href=»#page2″>Page2</a>
<a href=»#page3″>Page3</a>
<a href=»#page4″>Page4</a>
</ul>
</div>
|
По умолчанию модуль ng-route использует ! приставка. Однако здесь мы используем только # перед нашими страницами для маршрутизации. Это делается с hashPrefix атрибута hashPrefix используемого в конфигурации, который я объясню позже в соответствующем разделе. А пока прими это как есть.
Наш окончательный HTML-файл выглядит следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<html>
<head>
<link href=»style.css» rel=»stylesheet»>
</head>
<body>
<div id=»mainWrapper» ng-app=»mainApp»>
<div id=»fixedContent»>
<ul>
<a href=»#page1″>Page1</a>
<a href=»#page2″>Page2</a>
<a href=»#page3″>Page3</a>
<a href=»#page4″>Page4</a>
</ul>
</div>
<div id=»wrapper»>
<div id=»routedContent» ng-view></div>
</div>
</div>
<script src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-route.js»></script>
<script src=»//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-animate.js»></script>
<script src=»angularApp.js»></script>
</body>
</html>
|
Стилизация главной страницы
Поскольку этот урок посвящен AngularJS, я не буду подробно останавливаться на стилях CSS. Если у вас есть знания CSS, стилизуйте страницу по своему желанию. В противном случае вы можете использовать стиль, который я приведу ниже.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
html, body{
margin: 0;
padding: 0;
}
#mainWrapper{
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px
}
#fixedContent{
margin-bottom: 50px;
}
#wrapper{
width: 350px;
}
#routedContent{
width: 350px;
position: absolute;
}
ul{
display: flex;
justify-content: space-between;
width: 350px;
margin: 0;
padding: 0;
}
a{
text-decoration: none;
color: #FFFFFF;
font-family: Arial;
list-style: none;
background-color: #cecece;
padding: 7px 10px;
border-radius: 2px;
}
|
Страницы для перенаправления
Каждая страница, которая будет перенаправлена в DIV с директивой ng-view внутри основного файла HTML, может иметь уникальную структуру HTML и стиль CSS.
Давайте начнем с page1.html .
Так как мы хотим определенный стиль для каждой страницы, нам нужны отдельные файлы CSS для каждой страницы. Поэтому мы также создаем файл с именем page1.css , который будет содержать правила стилизации page1.html .
Основная структура HTML для page1 выглядит следующим образом:
|
1
2
3
4
5
6
|
<link href=»page1.css» rel=»stylesheet»>
<div id=»page1″>
<h1>Page 1</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
|
Вверху мы связались с CSS-файлом, который будет стилизовать страницу, и объявили DIV с идентификатором page1 , в который будет page1 весь контент.
Я сделаю это простым, но вам решать, как структурировать HTML-файл. Просто помните, что вашим контейнером всегда будет DIV, которому назначена директива ng-view . Таким образом, все в ваших перенаправленных страницах будет относительно этого DIV.
Стили page1.html приведены ниже:
|
1
2
3
4
5
6
7
|
#page1{
font-family: Arial;
}
h1{
color: #ffa42a;
}
|
Остальные три страницы могут быть совершенно разными, но для простоты я просто использую один и тот же шаблон для каждой HTML-страницы и немного разные CSS-файлы (разные цвета текста h1 ).
page2.html & page2.css
|
1
2
3
4
5
6
|
<link href=»page2.css» rel=»stylesheet»>
<div id=»page2″>
<h1>Page 2</h1>
<p>Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
</div>
|
|
1
2
3
4
5
6
7
|
#page2{
font-family: Arial;
}
h1{
color: cornflowerblue;
}
|
page3.html & page3.css
|
1
2
3
4
5
6
|
<link href=»page3.css» rel=»stylesheet»>
<div id=»page3″>
<h1>Page 3</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
|
|
1
2
3
4
5
6
7
|
#page3{
font-family: Arial;
}
h1{
color: #b2ce6f;
}
|
page4.html & page4.css
|
1
2
3
4
5
6
|
<link href=»page4.css» rel=»stylesheet»>
<div id=»page4″>
<h1>Page 4</h1>
<p>Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
</div>
|
|
1
2
3
4
5
6
7
|
#page4{
font-family: Arial;
}
h1{
color: #ff4517;
}
|
Установка ngRoute & ngAnimate в JavaScript
На данный момент мы завершили все необходимые файлы HTML и CSS. Теперь пришло время написать код JavaScript, который управляет маршрутизацией и анимацией.
Поскольку наша директива ng-app называется mainApp , мы используем этот идентификатор в функции модуля. Нам также нужно включить зависимости ngRoute и ngAnimate .
mainAngular = angular.module('mainApp',['ngRoute', 'ngAnimate']);
Теперь у нас есть доступ к $routeProvider и $locationProvider .
Мы будем использовать $routeProvider для управления маршрутизацией и $locationProvider для изменения hashPrefix , для которого установлено значение ! по умолчанию.
Мы используем .when('/page1', {templateUrl: 'page1.html'}) чтобы определить страницу, которая будет перенаправлена при нажатии <a href="#page1">Page1</a> в нашем основном HTML-файле.
Мы повторяем одну и ту же строку кода для каждой перенаправляемой страницы. В конце мы используем .otherwise({redirectTo: '/page1'}) , который обрабатывает неожиданные имена страниц. Если вы попытаетесь посетить неопределенное имя страницы, скажем page5 , вы будете перенаправлены на page1 .
Полный код JavaScript ниже:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var mainAngular = angular.module(‘mainApp’,[‘ngRoute’, ‘ngAnimate’]);
mainAngular.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when(‘/page1’,{
templateUrl: ‘page1.html’
})
.when(‘/page2’,{
templateUrl: ‘page2.html’
})
.when(‘/page3’,{
templateUrl: ‘page3.html’
})
.when(‘/page4’,{
templateUrl: ‘page4.html’
})
.otherwise({
redirectTo: ‘/page1’
});
$locationProvider.hashPrefix(»);
});
|
Дополнительное примечание: Если вы хотите добавить конкретную директиву ng-controller для любых страниц, подлежащих маршрутизации, вы можете обработать это внутри $routeProvider .
Пример для page1 :
|
1
2
3
4
|
.when(‘/page1’,{
templateUrl: ‘page1.html’,
controller: ‘page1Controller’
})
|
В конце наша страница должна выглядеть следующим образом, и вы сможете перемещаться между страницами без анимации перехода.

Анимация переходов страниц
Теперь пришло время оживить переходы маршрута.
Для анимации AngularJS имеет встроенные CSS-классы благодаря зависимости ngAnimate.
Те классы, которые мы собираемся использовать:
-
ng-enter: начальные стили CSS для анимации ввода. -
ng-enter-active: завершающие стили CSS для анимации ввода. -
ng-leave: начальные стили CSS для анимации выхода. -
ng-leave-active: завершающие стили CSS для анимации отпуска.
Таким образом, перенаправленный контент, поступающий на главную страницу, имеет переход от ng-enter к ng-enter-active . Аналогично, содержимое, покидающее главную страницу, имеет переход от ng-leave к ng-leave-active .
Мы должны присоединить вышеупомянутые классы к нашему классу routedContent .
Пример перехода приведен ниже. Вы можете создать свою собственную анимацию перехода или использовать ее в своем файле style.css .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#routedContent.ng-enter{
transform: translateX(-500px);
opacity: 0;
-webkit-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-moz-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-ms-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-o-transition: all 0.35s cubic-bezier(1,.01,0,.99);
transition: all 0.35s cubic-bezier(1,.01,0,.99);
}
#routedContent.ng-enter-active{
transform: translateX(0px);
opacity: 1;
}
#routedContent.ng-leave{
transform: translateX(0);
opacity: 1;
-webkit-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-moz-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-ms-transition: all 0.35s cubic-bezier(1,.01,0,.99);
-o-transition: all 0.35s cubic-bezier(1,.01,0,.99);
transition: all 0.35s cubic-bezier(1,.01,0,.99);
}
#routedContent.ng-leave-active{
transform: translateX(500px);
opacity: 0;
}
|
Я создал репозиторий GitHub с конечным результатом . Вы можете скачать или клонировать код там, чтобы попробовать его.
Вывод
В этом уроке мы рассмотрели, как создавать приложения SPA с помощью модуля ng-route AngularJS, а затем анимировали переходы с помощью CSS-классов ng-animate .
Используя только четыре CSS-класса, предоставляемых ng-animate , вы можете создавать различные анимации. Вы всегда можете прикрепить дополнительные классы, чтобы иметь больше контроля над анимацией перехода. Например, вы можете сделать так, чтобы ваши переходы страниц учитывали направление.
Я также упомянул, что, прикрепляя директиву controller к каждой конкретной странице внутри $routeProvider , вы можете получить дополнительный контроль над каждой страницей.
JavaScript с его библиотеками, такими как Angular, стал одним из де-факто языков работы в сети. Это не без кривых обучения, и есть множество фреймворков и библиотек, которые также могут вас занять. Если вы ищете дополнительные ресурсы для обучения или использования в своей работе, посмотрите, что у нас есть на Envato Market .
Я надеюсь, что этот урок дал вам общее представление о том, как использовать модули ng-route и ng-animate вместе.