开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜