jQuery $.address() plugin: hashbang links colliding with HTML5 state support
Here's a scenario that describes the problem:
User A has a browser with HTML5 state support, and sends this link to User B:
http://domain.tld/node
User B, who uses a browser without HTML 5 state support, navigates to another node, and sends the link back to User A:
http://domain.tld/node#!/another-node
But when User A clicks the link, the content for /node
is shown instead of /another-node
.
Querying Asual's jQuery $.address()
plugin shows that it is interpreting the "hashbang address" as开发者_开发技巧 the hash value:
> $.address.value()
"/node#/another-node"
> $.address.path()
"/node"
> $.address.hash()
"/another-node"
(Curiously the "!" is dropped from the hashbang.)
Can this ambiguity be overcome with a change in my implementation?
I could disable support for the history API if a hashbang is found in the URI, but I'd rather not.
I was able to solve this issue by changing my implementation a bit.
Basically, I determine what the address should be based on the browser's capabilities, check that against what the address actually is, and if it doesn't match, use location.replace()
to replace the address without creating a new history entry.
var addressValue = $.address.value(),
initPath = window.location.pathname.replace(stateBasePath, ""),
newLocation = baseUrl +stateBasePath + (supports_history_api() ? "" : "/#!") + (addressValue != "/" ? addressValue : initPath + window.location.search);
if (newLocation != window.location.href) {
window.location.replace(newLocation);
}
This code should be executed as soon as possible – outside of a DOM ready function.
stateBasePath
is equivalent to the value you would use for$.address.state()
(just an empty string if the site is located at the document root)baseUrl
is the URI protocol and domain, e.g.http://domain.tld
(no trailing slash)supports_history_api()
is a little ditty taken from Mark Pilgrim
精彩评论