具有 window.history.pushState 和回退的跨浏览器 jquery ajax 历史记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4250553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cross-browser jquery ajax history with window.history.pushState and fallback
提问by Binyamin
I want to implement a navigation history using jQuery and AJAX in a cross-browser manner. My approach is to use window.history.pushState
and fall back to a hash url /#!/url
in browsers that do not support window.history.pushState
.
我想以跨浏览器的方式使用 jQuery 和 AJAX 实现导航历史记录。我的方法是使用window.history.pushState
和回落到一个哈希URL/#!/url
中不支持的浏览器window.history.pushState
。
For example:
例如:
<a href="/home">home</a>
<a href="/about">about</a>
<a href="/contact">contact</a>
On browsers that support window.history.pushState
, clicking on one of these links should change address without page refresh to http://domain.com/home, http://domain.com/aboutetc. When the browser does not support window.history.pushState
, it should use a fragment identifier, i.e: http://domain.com/#!/home, http://domain.com/#!/about.
在支持的浏览器上window.history.pushState
,点击这些链接之一应该将不刷新页面的地址更改为http://domain.com/home, http://domain.com/about等。当浏览器不支持时window.history.pushState
,应该使用片段标识符,即:http://domain.com/#!/home、http://domain.com/#!/about。
Update: Based on the feedback here I have implemented Ajax SEO(git) that uses
jQuery Addressfor HTML5 History API with old browser fallback to /#!/url
.
更新:根据这里的反馈,我实现了Ajax SEO( git),它使用
jQuery Addressfor HTML5 History API,旧浏览器回退到/#!/url
.
回答by Ben Lee
// Assuming the path is retreived and stored in a variable 'path'
if (typeof(window.history.pushState) == 'function') {
window.history.pushState(null, path, path);
} else {
window.location.hash = '#!' + path;
}
回答by Koen.
Something i've been using with fallback hash URL's:
我一直在使用后备哈希 URL 的东西:
History = History || {};
History.pathname = null;
History.previousHash = null;
History.hashCheckInterval = -1;
History.stack = [];
History.initialize = function () {
if (History.supportsHistoryPushState()) {
History.pathname = document.location.pathname;
$(window).bind("popstate", History.onHistoryChanged);
} else {
History.hashCheckInterval = setInterval(History.onCheckHash, 200);
}
};
History.supportsHistoryPushState = function () {
return ("pushState" in window.history) && window.history.pushState !== null;
};
History.onCheckHash = function () {
if (document.location.hash !== History.previousHash) {
History.navigateToPath(document.location.hash.slice(1));
History.previousHash = document.location.hash;
}
};
History.pushState = function (url) {
if (History.supportsHistoryPushState()) {
window.history.pushState("", "", url);
} else {
History.previousHash = url;
document.location.hash = url;
}
History.stack.push(url);
};
History.onHistoryChanged = function (event) {
if (History.supportsHistoryPushState()) {
if(History.pathname != document.location.pathname){
History.pathname = null;
History.navigateToPath(document.location.pathname);
}
}
};
History.navigateToPath = function(pathname) {
History.pushState(pathname);
// DO SOME HANDLING OF YOUR PATH HERE
};
You could bind your click events to this with:
您可以将您的点击事件绑定到此:
$(function(){
$("a").click(function(){
var href = $(this).attr('href');
History.navigateToPath( href )
return false;
});
});
If you need some more explanation on this example i'll be glad to hear it.
如果你需要对这个例子做更多的解释,我会很高兴听到的。
EDIT
编辑
Please see my other answer.
请看我的另一个回答。
回答by Koen.
It has been a while since my original answerand I would now suggest using Backbone.
我的原始答案已经有一段时间了,我现在建议使用Backbone。
An implementation could be:
一个实现可以是:
// First setup a router which will be the responder for URL changes:
var AppRouter = Backbone.Router.extend({
routes: {
"*path": "load_content"
},
load_content: function(path){
$('#content').load('/' + path);
}
});
var appRouter = new AppRouter;
// Then initialize Backbone's history
Backbone.history.start({pushState: true});
Excerpt from the documentation:
文档摘录:
To indicate that you'd like to use HTML5
pushState
support in your application, useBackbone.history.start({pushState: true})
. If you'd like to usepushState
, but have browsers that don't support it natively use full page refreshes instead, you can add{hashChange: false}
to the options.
要表明您希望
pushState
在应用程序中使用 HTML5支持,请使用Backbone.history.start({pushState: true})
. 如果您想使用pushState
,但浏览器本身不支持它,而是使用整页刷新,您可以添加{hashChange: false}
到选项中。
And now every time Backbone.history.navigate
is called, the AppRouter
will perform an AJAX load of the path into the #content
div.
现在每次Backbone.history.navigate
调用时,AppRouter
都会将路径的 AJAX 加载到#content
div 中。
To handle all links with AJAX you could use the following:
要使用 AJAX 处理所有链接,您可以使用以下命令:
$("a").on('click', function(event){
event.preventDefault();
Backbone.history.navigate( event.currentTarget.pathname, {trigger: true} )
});
Take note of the {trigger: true}
which causes the handler in the router to be called (otherwise only from url changes).
请注意{trigger: true}
导致路由器中的处理程序被调用的原因(否则仅来自 url 更改)。