Wednesday, February 22, 2012

Change browser url without page reloading with ajax request using JavaScript, HTML5 history API, jQuery, PHP like Facebook, Github navigation menu

When you are working with ajax, the problem is that after you have loaded some content using ajax, you can't change the URL of the browser according to the content. Because of this, reloading the page causes the new ajax content to disappear and it shows the previous page. Although you can resolve this problem with having some hash tag in the URL, but having hash tag in the url for navigation won't be SEO friendly.



Do you ever wonder when you are working Facebook or Github in a HTML5 supported browser, when you click on the links, the content is loaded into the page using ajax and at the same time the URL changes in the browser according to the specific page but without hash tag in the URL.

This makes use of the HTML5 History API to change the browser URL without refreshing the page.

Consider a page that has the following links to three menu items and a div to display the ajax content.


<div id="menu">
<a href="menu1.php" rel="tab">menu1</a> |
<a href="menu2.php" rel="tab">menu2</a> |
<a href="menu3.php" rel="tab">menu3</a>
</div>

To override the default action for the link(anchor tag), use the following jQuery code snippet.


$(function(){
$("a[rel='tab']").click(function(e){
//code for the link action
return false;
});
});

Now to get the ajax content and display it and change the browser URL to the specific location without refresh use the following code.


$(function(){
$("a[rel='tab']").click(function(e){
//e.preventDefault();
/*
if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content;
if commented, html5 nonsupported browers will reload the page to the specified link.
*/

//get the link location that was clicked
pageurl = $(this).attr('href');

//to get the ajax content and display in div with id 'content'
$.ajax({url:pageurl+'?rel=tab',success: function(data){
$('#content').html(data);
}});

//to change the browser URL to the given link location
if(pageurl!=window.location){
window.history.pushState({path:pageurl},'',pageurl);
}
//stop refreshing to the page given in
return false;
});
});

For this HTML5 History API, the back button functionality won't work as normal. So we need to override back button to get the ajax content without reloading the page.
To do this add the following code snippet in the page.


/* the below code is to override back button to get the ajax content without page reload*/
$(window).bind('popstate', function() {
$.ajax({url:location.pathname+'?rel=tab',success: function(data){
$('#content').html(data);
}});
});

For the HTML5 History API non supported browsers, those links will reload the page to the specific location. But if its supported, you are lucky; it will get only the required content using ajax and display it without reloading the entire page.

Live Demo | Download Code

8 comments:

  1. tat's really awsum...! dis s wat am looking....

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Great post! Much easier to implement than I expected. One question though, is it possible to include a loading indicator between pages? Thanks.

    ReplyDelete
  4. error Undefined index: rel in codeignitor

    ReplyDelete