Skip to content

Instantly share code, notes, and snippets.

@kaizau
Created May 29, 2011 21:59
Show Gist options
  • Save kaizau/998161 to your computer and use it in GitHub Desktop.
Save kaizau/998161 to your computer and use it in GitHub Desktop.
Bugfix for [bcherry's](https://github.com/bcherry) pathchange proof of concept (IE needs quotes on attribute selectors - lines 66, 74)
// Plugin that provides a "pathchange" event on the window object, notifying an application when the URL changes
// This is accomplished by watching the hash, using the hashchange event from HTML5 or a polling interval in older browsers.
// In addition, in some modern browsers, HTML5 History Management is used to support changing the URL's path without reloading the page.
// This plugin also provides a method to navigate to a URL safely, that will use HTML5 History Management to avoid a page load.
// Everything degrades gracefully, and supports RESTful client development.
// Browser Support:
// Chrome - Any recent version of Chrome supports everything.
// Safari - Any recent version of Safari supports everything.
// Firefox - Newer versions of Firefox support the hashchange event
// Firefox 4 betas also support HTML5 History Management
// Internet Explorer - IE8 supports hashchange
// IE6 and 7 receive inferior hashchange support through a polling interval.
// Others - Other modern browsers probably support some subset of features.
// This plugin was authored by Ben Cherry (bcherry@gmail.com), and is released under an MIT License (do what you want with it).
// Some of the code in this plugin was adapted from Modernizr, which is also available under an MIT License.
(function($) {
// can use $(window).bind("pathchange", fn) or $(window).pathchange(fn)
$.fn.pathchange = function(handler) {
return handler ? this.bind("pathchange", handler) : this.trigger("pathchange");
};
var my = $.pathchange = {
// default options
options: {
useHistory: true, // whether we use HTML5 History Management to change the current path
useHashchange: true, // whether we use HTML5 Hashchange to listen to the URL hash
pollingInterval: 250, // when using Hashchange in browsers without it, how often to poll the hash (in ms)
interceptLinks: true, // do we intercept all relative links to avoid some page reloads?
disableHashLinks: true // do we ensure all links with href=# are not followed (this would mess with our history)?
},
// call this once when your app is ready to use pathchange
init: function(options) {
var lastHash;
$.extend(my.options, options);
// Listen to the HTML5 "popstate" event, if supported and desired
if (my.options.useHistory && my.detectHistorySupport()) {
$(window).bind("popstate", function(e) {
$(window).trigger("pathchange");
});
}
// Listen to the HTML5 "hashchange" event, if supported and desired
if (my.options.useHashchange) {
$(window).bind("hashchange", function(e) {
$(window).trigger("pathchange");
});
// Hashchange support for older browsers (IE6/7)
if (!my.detectHashchangeSupport()) {
lastHash = window.location.hash;
setInterval(function() {
if (lastHash !== window.location.hash) {
$(window).trigger("hashchange");
lastHash = window.location.hash;
}
}, my.options.pollingInterval);
}
}
// Intercept all relative links on the page, to avoid unneccesary page refreshes
if (my.options.interceptLinks) {
$("body").delegate("a[href^='/']", "click", function(e) {
my.changeTo($(this).attr("href"));
e.preventDefault();
});
}
// Ensure all the href=# links on the page don't mess with things
if (my.options.disableHashLinks) {
$("body").delegate("a[href='#']", "click", function(e) {
e.preventDefault();
});
}
},
// Call to manually navigate the app somewhere
changeTo: function(path) {
// If we're using History Management, just push an entry
if (my.options.useHistory && my.detectHistorySupport()) {
window.history.pushState(null, null, path);
$(window).trigger("pathchange");
} else {
// Make sure there's a hash (going from foo.com#bar to foo.com would trigger a reload in Firefox, sadly)
if (path.indexOf("#") < 0) {
path += "#";
}
// Otherwise, navigate to the new URL. Might reload the browser. Might trigger a hashchange.
window.location.href = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "") + path;
}
},
// Simple feature detection for History Management (borrowed from Modernizr)
detectHistorySupport: function() {
return !!(window.history && history.pushState);
},
// Simple feature detection for hashchange (adapted from Modernizr)
detectHashchangeSupport: function() {
var isSupported = "onhashchange" in window;
if (!isSupported && window.setAttribute) {
window.setAttribute("onhashchange", "return;");
isSupported = typeof window.onhashchange === "function";
}
return isSupported;
}
};
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment