I try to implement pushstate history on my website in order to load content from a single.php page inside a index.php container.
My website have two main page : index.ph
I found a way to make it works great!
I made a script that use pushstate for HTML5 web browser with an hashbang fallback in HTML4 web browser (it works since IE8)
To fix the refresh browser problem (without using rewrite rules in .htaccess), I added a little script on the head of the single.php page in order to redirect (only if you are javascript enable) to index.php while getting the pathname of the window.
single.php script (in the head, at the top of the head!):
self.name= window.location.pathname;
window.location.replace(".");
Script for pushstate and hashbang fallback:
if(self.name){
refreshdocumenttitle = document.title;
refrestitle = self.name;
refreshurl = self.name;
if (typeof(window.history.pushState) == 'function') {
refrestitle = self.name.substring(1).replace(/-/g," ");
refreshurl = self.name.replace("#!", "");
}else {
window.location.hash = '#!' + refreshurl.substring(1);
}
load_content(refrestitle, refreshurl);
}
$(document).on('click','.link', function(){
link= $(this);
if (!link.hasClass('current')) {
$(".link").removeClass('current');
link.addClass('current');
$post_link = link;
load_content($post_link.attr('title'),$post_link.attr('href'));
return false;
}
return false;
});
window.onpopstate = function(event) {
$(".link").removeClass('current');
url = window.location.hash;
if (url != '') {
title = url.substring(2).replace(/-/g," ");
url = "/" + url.replace("#!", "");
load_content(title,url);
}
if (event.state) {
load_content(event.state.title, window.location.pathname, true);
} else {
if (!self.name) {
if (typeof refrestitle !== 'undefined') {
pathname = window.location.pathname;
if (pathname == "/") {
document.title = refreshdocumenttitle;
}
}
var stateObj = {
title: document.title,
url: window.location.pathname,
};
window.history.replaceState(stateObj,document.title,window.location.pathname);
load_content(document.title, window.location.pathname, true);
}
}
self.name= '';
}
$(window).on('hashchange', function() {
if (typeof(window.history.pushState) !== 'function') {
var hash = "/" + location.hash.replace("#!", "");
if(window.location.hash) {
load_content(hash.substring(1).replace(/-/g," "), hash);
} else {
load_content("", "")
}
self.name= '';
}
})
$(window).trigger('hashchange');
function load_content(title,url,skipHistory) {
$.get(url,function (data) {
document.title = title;
var stateObj = {
title: title,
url: url
};
if (!skipHistory) {
if (typeof(window.history.pushState) == 'function') {
window.history.pushState(stateObj,title.replace(/-/g," "),url);
}else {
if( url != "") {
window.location.hash = '#!' + url.substring(1);
}
}
}
if( window.location.hash != "" || window.location.pathname != "/" ) {
$("#ajaxify_container").html("loading...");
$("#ajaxify_container").load('single.php?page='+url.substring(1)+' #container-2');
}
else {
$("#ajaxify_container").html("");
}
});
}
In this script, I check on load if the pathname have an hashbang or if it's just a normal path. If the browser can support pushstate, I change hashbang to normal pathname. If the browser don't support pushstate and if pathname have a normal pathname I add an hashbang.
Then, for HTML5 history I use onpopstate and for HTML4 I use hashchange to support back, prev button and refresh browser (because of my script in the head of the single.php page).
If javascript is disabled or if the browser can't handle hashbang or pushstate, the single page can be loaded normally and all necessary informations are displayed like a normal page.
So everything works with or without javascript. It's SEO friendly!! Googlebot crawled all my links with the right content of each dynamic single.php page!