Skip to content

Instantly share code, notes, and snippets.

@markbrown4
Created March 4, 2011 01:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markbrown4/853984 to your computer and use it in GitHub Desktop.
Save markbrown4/853984 to your computer and use it in GitHub Desktop.
Lighter version of pushState / hash fallback with strict URL convention
/* Uses a strict URL convention, specifically a language code as an identifier for the root of the site and then the page name.
* e.g. http://example.com/cool-site/en/listing/?cool=true
* Lang = 'en'
* Page = 'listing'
* The URL's for the pages and the ajax content are identical,
* We just used the X-Requested-With header to serve the content only if it's an ajax request.
*/
var History = {
lang: 'en|es|de|fr|pt|zh-s|zh-c|ja|ko|id|th|en-us|it',
page: 'listing',
previous: { page: 'listing' },
slashRegex: new RegExp('\/('+lang+')$'),
urlRegex: new RegExp('(.*)\/('+lang+')\/?(#!)?\/?([a-z]*)?\/?(.*)?'),
init: function() {
History.initPage();
if (history.pushState) {
History.preventPageInit = true;
addEvent(window, 'popstate', History.stateChange);
}
else {
if ("onhashchange" in window) {
addEvent(window, 'hashchange', History.stateChange);
}
else {
History.initIframe();
setInterval(function() {
if (window.location.hash != idoc.location.hash) {
if (window.location.hash != History.hash) {
iDoc.open();
iDoc.close();
History.hash = idoc.location.hash = window.location.hash;
}
if (iDoc.location.hash != History.hash) {
History.hash = window.location.hash = idoc.location.hash;
}
History.stateChange();
}
}, 100);
}
}
},
initURL: function() {
History.hash = window.location.hash;
var url = String(window.location);
var match = url.match(History.slashRegex);
if (match) url += '/';
url = url.match(History.urlRegex);
if (!url) { return; } // Can't match url
History.page = (url[4]) ? url[4] : History.page;
if (!url[4] || (!history.pushState && !url[3] && url[4])) {
url[3] = '#!';
url[4] = History.page;
url.shift(0);
var defaultURL = url.join('/');
if (history.pushState) {
history.pushState({page: History.page}, '', defaultURL.replace('/#!/','/'));
}
else if (History.hash == '') {
window.location = defaultURL;
}
}
},
initIframe: function() {
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
History.iDoc = iframe.contentWindow.document;
History.iDoc.open();
History.iDoc.close();
},
initPage:function() {
if (History.preventPageInit) { History.preventPageInit = false; return; }
if (History.PageInitializers[History.page]) {
var url = String(window.location).replace('/#!/','/');
History.PageInitializers[History.page](url);
}
},
stateChange: function(event) {
if (event && event.state) {
History.page = event.state.page;
}
else {
var url = String(window.location).match(History.urlRegex);
History.page = url[4];
}
History.initPage();
},
load: function(options) {
options = extend({
page: 'listing',
title: '',
url: ''
},options);
History.previous = {
page: History.page,
title: document.title,
url: String(window.location),
scroll: window.scrollY || document.documentElement.scrollTop || 0
};
document.title = (options.title != '') ? options.title: document.title;
if (history.pushState) {
history.pushState({page: options.page}, options.title, options.url);
History.stateChange();
}
else {
var url = String(options.url).match(History.urlRegex);
var u = '!/' + url[4];
if (url[5]) u += '/' + url[5]
window.location.hash = u;
}
}
}
History.PageInitializers = {
default: function(url) {
// init page
}
}
History.initURL();
addEvent(window, 'load', function() {
History.init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment