可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 5 years ago.
I am looking into using the HTML5 History API to resolve deep linking problems with AJAX loaded content, but I am struggling to get off the ground. Does any one know of any good resources?
I want to use this as it seems a great way to allow to the possibility of those being sent the links may not have JS turned on. Many solutions fail when someone with JS sends a link to someone without.
My initial research seems to point to a History API within JS, and the pushState method.
http://html5demos.com/history
回答1:
For a great tutorial the Mozilla Developer Network page on this functionality is all you'll need: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
Unfortunately, the HTML5 History API is implemented differently in all the HTML5 browsers (making it inconsistent and buggy) and has no fallback for HTML4 browsers. Fortunately, History.js provides cross-compatibility for the HTML5 browsers (ensuring all the HTML5 browsers work as expected) and optionally provides a hash-fallback for HTML4 browsers (including maintained support for data, titles, pushState and replaceState functionality).
You can read more about History.js here:
https://github.com/browserstate/history.js
For an article about Hashbangs VS Hashes VS HTML5 History API, see here:
https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling
回答2:
I benefited a lot from 'Dive into HTML 5'. The explanation and demo are easier and to the point.
History chapter - http://diveintohtml5.info/history.html
and history demo - http://diveintohtml5.info/examples/history/fer.html
回答3:
Keep in mind while using HTML5 pushstate if a user copies or bookmarks a deep link and visits it again, then that will be a direct server hit which will 404 so you need to be ready for it and even a pushstate js library won't help you. The easiest solution is to add a rewrite rule to your Nginx or Apache server like so:
Apache (in your vhost if you're using one):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Nginx
rewrite ^(.+)$ /index.html last;
回答4:
The HTML5 history spec is quirky.
history.pushState()
doesn't dispatch a popstate
event or load a new page by itself. It was only meant to push state into history. This is an "undo" feature for single page applications. You have to manually dispatch a popstate
event or use history.go()
to navigate to the new state. The idea is that a router can listen to popstate
events and do the navigation for you.
Some things to note:
history.pushState()
and history.replaceState()
don't dispatch popstate
events.
history.back()
, history.forward()
, and the browser's back and forward buttons do dispatch popstate
events.
history.go()
and history.go(0)
do a full page reload and don't dispatch popstate
events.
history.go(-1)
(back 1 page) and history.go(1)
(forward 1 page) do dispatch popstate
events.
You can use the history API like this to push a new state AND dispatch a popstate event.
history.pushState({message:'New State!'}, 'New Title', '/link');
window.dispatchEvent(new PopStateEvent('popstate', {
bubbles: false,
cancelable: false,
state: history.state
}));
Then listen for popstate
events with a router.
回答5:
You could try Davis.js, it gives you routing in your JavaScript using pushState when available and without JavaScript it allows your server side code to handle the requests.
回答6:
Here is a great screen-cast on the topic by Ryan Bates of railscasts. At the end he simply disables the ajax functionality if the history.pushState method is not available:
http://railscasts.com/episodes/246-ajax-history-state
回答7:
You may want to take a look at this jQuery plugin. They have lots of examples on their site. http://www.asual.com/jquery/address/
回答8:
I've written a very simple router abstraction on top of History.js, called StateRouter.js. It's in very early stages of development, but I am using it as the routing solution in a single-page application I'm writing. Like you, I found History.js very hard to grasp, especially as I'm quite new to JavaScript, until I understood that you really need (or should have) a routing abstraction on top of it, as it solves a low-level problem.
This simple example code should demonstrate how it's used:
var router = new staterouter.Router();
// Configure routes
router
.route('/', getHome)
.route('/persons', getPersons)
.route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();
Here's a little fiddle I've concocted in order to demonstrate its usage.
回答9:
if jQuery is available, you could use jQuery BBQ