How to Change Pages in a Web Application in the Age of HTML5
Join the DZone community and get the full member experience.
Join For FreeMore and more web sites stop to use the old way of request-response
page switches, where each page switch refreshes the entire page in the
browser.
Instead they refresh just the data and the page itself is not reloaded.
This way has better for performance and it also makes a much smoother user experience.
You can see a great example in github where you click on one of the files.
In this post I am going to explain how this is achieved step by step.
My Demo
Requirements:
For some reason, almost all of the examples I saw on the internet about this used jquery in one way or another.
This post is NOT using any third-party libraries except for history.js script for browsers which do not support the history.pushState feature. I took this script from github.
Step 1 – handle links
We want that pressing a link will trigger a JavaScript function.
You can do that in many ways.
I have done it like this:
var elements = document.getElementsByTagName('a'); var address; for(var i=0; i<elements.length;i++){ element=elements[i]; address=element.getAttribute('href'); if(address.substring(0,2)=="./"){ //inner links only element.setAttribute('onclick','goto("'+address+'",event)'); } }
It will go over all the links in the page and will attach a call to
function goto(), but it will do it just for the links which points to
inner pages.
The goto() function gets the address of the page and the click event.
In this way you write you link tags as usual.
Step 2 – prevent page redirection
We want that pressing on a link will not cause the web page to be
redirected, so we need prevent the default behavior of the click event
on the link.
This is how it is done:
theEvent.preventDefault();
Step 3 – load data in Ajax
We now need to get the data that will be refreshed from the server.
There are endless implementations for that.
Here is what I used.
function ajax(page){ var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else{// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function(){ if (xmlhttp.readyState==4 && xmlhttp.status==200){ updateText(xmlhttp.responseText); //the method to be called when the data is fetched } } xmlhttp.open("GET","test.php?page="+page,true); xmlhttp.send(); }
Of course you will have to put the data on the server. I have used in my example a simple php page which receives the page as a parameter, but you can also use static html files.
Step 4 – update page data in an inner div
After you got the the data from the server you need to print it on the screen.
You can so it simply like this:
document.getElementById('myDiv').innerHTML = theData;
In my example I used an animation which makes things a bit cooler, I will talk about that later on.
Step 5 – push the page to the history
In regular page switch, the new page address is updated in the browser
address bar and it also enters the history stack of the browser.
We will imitate this behavior like this:
history.pushState('', pageTitle, pageAddress);
Step 6 – handle history back/forward actions
Now that we have pushed our new fake page to the history stack we also
need to be prepared when this fake page is popped from the history.
window.onpopstate = function(event) { var currentPage = location.pathname; updateContent(); }
Step 7 – handle pages mapping in your server for direct links
You probably also should be prepared for the possibility that users will want to access the inner pages directly.
You can achieve this by simple mapping in your web server.
Optional – add animation
You may chose to add some kind of animation, for example a clock while
the data is loaded or some kind of text effect like I have done.
This will make things even cooler.
I have used a typing animation. This is how I have implemented it:
function startAnimation(text){ clearInterval(start); thediv.innerHTML=""; thetext=text; if (document.getElementById||document.all){ start=setInterval("animation()",20); } } function animation(){ var oldLen = thediv.innerHTML.length; var finalLen = thetext.length; if(oldLen<finalLen){ thediv.innerHTML=thetext.substring(0,oldLen+1); } }
Existing implementations
You should know that if you wish you can just use one of the existing implemtations on the net.
Here is the very cool implementation by github.
Published at DZone with permission of Avi Yehuda, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments