Created
May 29, 2011 21:59
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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