Ok, I made this example for you. Start with the HTML ( index.html ):
<!DOCTYPE html> <html> <head> <title>Stackoverflow</title> <script type="text/javascript" src="sof.js"> </script> </head> <body onLoad="load();"> <ul id="menu"> <li><a href="/home">home</a></li> <li><a href="/about">about</a></li> <li><a href="/blog">blog</a></li> <li><a href="/photos">photos</a></li> </ul> <button onclick="back ();">Back</button> <button onclick="ff ();">Forward</button> <div> Action: <span id="action"></span><br/> Url: <span id="url"></span><br/> Description: <span id="description"></span> </div> </body> </html>
And then the javascript file ( sof.js ):
var menu, url, description, action, data, historyState, act;
function $ (id) {return document.getElementById (id);} // Updates infos function update (state) { action.innerHTML = act; url.innerHTML = state.url; description.innerHTML = state.description; } // Goes back function back () { act = 'Back'; history.back (); } // Goes forward function ff () { act = 'Forward'; history.forward (); } function load () { menu = $ ('menu'); url = $ ('url'); description = $ ('description'); action = $ ('action'); // State to save historyState = { home: { description: 'Homepage' } , about: { description: 'Infos about this website' } , blog: { description: 'My personal blog' } , photos: { description: 'View my photos' } }; // This is fired when history.back or history.forward is called window.addEventListener ('popstate', function (event) { var hs = history.state; if ((hs === null) || (hs === undefined)) hs = event.state; if ((hs === null) || (hs === undefined)) hs = window.event.state; if (hs !== null) update (hs); }); menu.addEventListener ('click', function (event) { var el = event.target; // Prevents url reload event.preventDefault (); // Handles anchors only if (el.nodeName === 'A') { // Gets url of the page historyState[el.innerHTML].url = el.getAttribute ('href'); // Creates a new history instance and it saves state on it history.pushState (historyState[el.innerHTML], null, el.href); act = 'Normal navigation'; update (historyState[el.innerHTML]); } }); // Handles first visit navigation var index = location.pathname.split ('/'); index = index[index.length-1]; if (index !== '') { historyState[index].url = location.pathname; history.pushState (historyState[index], null, location.pathname); act = 'First visit'; update (historyState[index]); } }
And .htaccess for direct request:
RewriteEngine On RewriteRule ^home$ ./index.html RewriteRule ^about$ ./index.html RewriteRule ^blog$ ./index.html RewriteRule ^photos$ ./index.htm
Each time an anchor is clicked, a new instance of history is pushed onto the history stack, and an object (called a state) is saved with it: the local url changes, but loading stops on the "event.preventDefault ()" method. In addition, some information is updated (such as URL, description and action).
Then, using the back and forward buttons, you can travel through history and use history.state (or event.state or window.event.state, it depends on browsers) to retrieve the current state.
And in the end, if you enter the entire URL directly into the address bar, it will work the same as above .htaccess;)
I hope this example helps you;)
Ciao
Wilk
PS: For more information: