Single-page applications allow you to refresh a certain portion of a web-page by routing any content stored in a separate .html file. By doing so, you do not reload your main page.
AngularJS provides a module named ngRoute exactly for this purpose.
Another useful module of AngularJS is ngAnimate, which makes it easy to animate with certain CSS classes.
In this tutorial I will try to explain each step thoroughly, although you still need a basic knowledge of AngularJS in order to be able to follow.
Starting With a Main Page
Basic Structure
This index.html file is going to be our main page where we have both fixed and routed content.
I will start with a basic HTML document and include all the necessary libraries along with our custom stylesheet named style.css
and a JavaScript file angularApp.js
.
Now I add two DIVs with id names of fixedContent
and routedContent
inside a mainWrapper
DIV.
routedContent
is also wrapped inside another DIV named wrapper
. That is because the routedContent
should be absolute positioned relative to a parent DIV due to the fact that during routing animation, two different pieces of content clash with each other.
As the id names imply, fixedContent
will be the static content of our main page, and routedContent
will be dynamically changing upon user interaction.
In order to define an Angular app in our HTML file, we need to use the ng-app
directive. Since the whole page will be an Angular app, we need to assign this directive to the mainWrapper
DIV.
We also need the ng-view
directive, which tells the DIV it is assigned to display the routed page content.
Now our index.html file looks like this:
Navigation Menu
We need a navigation menu in order to route different pieces of content to ng-view
.
We are going to use the ul
and a
elements to create a simple horizontal menu. Below you can see the HTML snippet for the menu structure.
Page1 Page2 Page3 Page4
By default, the ng-route
module uses the !
prefix. However, here we only use #
in front of our pages to be routed. This is done with the hashPrefix
attribute used in the configuration, which I’ll explain later in the related section. For now, take it as it is.
Our final HTML file is as follows:
Page1 Page2 Page3 Page4
Styling the Main Page
Since this tutorial focuses on AngularJS, I am not going to detail the CSS styling. If you have former CSS knowledge, style the page as you wish. Otherwise, you can use the styling I provide below.
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; }
Pages to Be Routed
Each page that will be routed to DIV with the ng-view
directive inside the main HTML file can have a unique HTML structure and CSS styling.
Let’s start with page1.html.
Since we want a specific styling for each page, we need separate CSS files for each page. Therefore, we also create a file named page1.css, which will contain the styling rules of page1.html.
The basic HTML structure for page1 is as follows:
Page 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
At the top, we linked to the CSS file that will be styling the page, and we declared a DIV with id name of page1
, where the whole content will be laid.
I will keep it simple, but it is completely up to you how to structure the HTML file. Just bear in mind that your container will always be the DIV to which the ng-view
directive is assigned. So everything in your routed pages will be relative to that DIV.
The styling of page1.html is given below:
#page1{ font-family: Arial; } h1{ color: #ffa42a; }
The other three pages can be totally different, but for the sake of simplicity I am just using the same template for each HTML page and slightly different CSS files (different h1
text-colors).
page2.html & page2.css
Page 2
Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
#page2{ font-family: Arial; } h1{ color: cornflowerblue; }
page3.html & page3.css
Page 3
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
#page3{ font-family: Arial; } h1{ color: #b2ce6f; }
page4.html & page4.css
Page 4
Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
#page4{ font-family: Arial; } h1{ color: #ff4517; }
Setting the ngRoute & ngAnimate in JavaScript
So far we have completed all the necessary HTML and CSS files. Now it is time to write the JavaScript code that controls the routing and animation.
Since our ng-app
directive is named mainApp, we use this id in the module function. We also need to include the ngRoute
and ngAnimate
dependencies.
mainAngular = angular.module('mainApp',['ngRoute', 'ngAnimate']);
Now we have access to $routeProvider
and $locationProvider
.
We are going to use the $routeProvider
to manage the routings and $locationProvider
to change the hashPrefix
, which is set to !
by default.
We use .when('/page1', {templateUrl: 'page1.html'})
to define the page to be routed when Page1
is clicked in our main HTML file.
We repeat the same line of code for each page to be routed. At the end, we use .otherwise({redirectTo: '/page1'})
, which handles unexpected page names. If you try to visit an undefined page name, say page5
, you will be redirected to page1
.
The complete JavaScript code is below:
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(''); });
Extra Note: If you wish to add a specific ng-controller
directive for any pages to be routed, you can handle this inside the $routeProvider
.
An example for page1:
.when('/page1',{ templateUrl: 'page1.html', controller: 'page1Controller' })
In the end, our page should look like this, and you should be able to navigate between pages with no transition animations.
Animating the Page Transitions
Now it is time to animate the route transitions.
For animation purposes, AngularJS has built-in CSS classes thanks to the ngAnimate dependency.
Those classes that we are going to use are:
-
ng-enter
: The starting CSS styles for the enter animation. -
ng-enter-active
: The finishing CSS styles for the enter animation. -
ng-leave
: The starting CSS styles for the leave animation. -
ng-leave-active
: The finishing CSS styles for the leave animation.
So the routed content which is coming into the main page has a transition from ng-enter
to ng-enter-active
. Likewise, the content leaving the main page has a transition from ng-leave
to ng-leave-active
.
We have to attach the above mentioned classes to our routedContent
class.
An example transition is given below. You can either design your own transition animations or use this one inside your style.css file.
#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; }
Below is the final result of the project on Plunker.
Conclusion
In this tutorial, we covered how to create SPA applications with the ng-route
module of AngularJS, and then we animated the transitions through the CSS classes of ng-animate
.
By using only four CSS classes provided by ng-animate
, you can achieve various animations. You can always attach extra classes to have more control over the transition animations. For example, you can make your page transitions direction-aware.
I also mentioned that by attaching the controller
directive to each specific page inside the $routeProvider
, you can achieve extra control over each page.
JavaScript, with its libraries such as Angular, has become one of the de facto languages of working on the web. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available on Envato Market.
I hope this tutorial gave you an overall idea of how to utilize the ng-route
and ng-animate
modules together.
Powered by WPeMatico