HTML5历史记录API:不能多次向后退 [英] HTML5 history API: cannot go backwards more than once
问题描述
我一直试图使我的脚本正常工作,但显然有问题:当我尝试使用浏览器后退按钮向后移动时,它会在第一页上向后停止,即第二次单击后退按钮,无法正常工作,而是使用其自身更新当前页面.
I have been trying to get my script working but apparently there is something wrong with it: when I try to go backwards with the browser back button, it stops at the first page backwards i.e. the second time I click the back button, does not work properly and instead updates the current page with itself.
示例: 主页->第二页->第三页->第二页->第二页->第二页(依此类推)
Examples: homepage -> second page -> third page -> second page -> second page -> second page (and so on)
主页->第二页->第三页->第四页->第三页->第三页(依此类推)
homepage -> second page -> third page -> fourth page -> third page-> third page (and so on)
这反而有效: 主页->第二页->主页
This instead works: homepage -> second page -> homepage
有人知道我失踪了吗?
var domain = 'http://example.com/';
function updatePage(json){
var postData = JSON.parse(json);
// pushState
var url = domain + postData.url;
var title = postData.title;
document.title = title;
history.pushState({"page": url}, title, url);
// Clears some elements and fills them with the new content
// ...
// Creates an 'a' element that triggers AJAX for the next post
var a = document.createElement('a');
a.innerHTML = postData.next;
a.href = domain + postData.next;
document.getElementById('container').appendChild( a );
listenerAttacher( a );
// Creates another 'a' element that triggers AJAX for the previous post
a = document.createElement('a');
a.innerHTML = postData.previous;
a.href = domain + postData.previous;
document.getElementById('container').appendChild( a );
listenerAttacher( a );
}
function loadPost( resource ){
// Loads post data through AJAX using a custom function
loadHTML( resource, function(){
updatePage( this.responseText );
});
}
function listenerAttacher( element ){
// Adds a click listener to an element.
element.addEventListener('click', function(e){
e.preventDefault();
e.stopPropagation();
loadPost( this.href +'.json' );
return false;
},
false);
}
(function(){
history.replaceState({'page': window.location.href}, null, window.location.href);
// Adds the event listener to all elements that require it.
var titles = document.querySelectorAll('.post-title');
for (var i = 0; i < titles.length; i++){
listenerAttacher( titles[i] );
}
// Adds a popstate listener
window.addEventListener('popstate', function(e){
if ( e.state == null || e.state.page == domain ){
window.location = domain;
}
else {
loadPost( e.state.page + '.json' );
}
}, false);
})();
推荐答案
按下返回按钮时,将触发popstate
事件并调用loadPost
函数.但是,在loadPost
中,再次调用history.pushState
方法,这会将当前页面再次推送到历史记录堆栈中.这就解释了为什么第一个后退按钮可以工作,然后却不能工作的原因.
When you pressed back button, popstate
event is fired and loadPost
function is called. However in loadPost
, history.pushState
method is called again, which pushes the current page on the history stack again. Which explains why the first back button works and then it does not.
1)一种快速解决方案是检查当前状态是否与您要推送的状态相匹配:
1) A quick fix is to check if the current state matches the state you are trying to push:
if (!history.state || history.state.page!=url)
history.pushState({ "page": url }, title, url);
2)事件更好,您可以在loadPost
和updatePage
函数中添加参数,以防止不必要的pushState
调用:
2) Event better, you can add parameter to loadPost
and updatePage
functions to prevent unnecessary pushState
calls:
function updatePage(json, disablePushState) {
...
// disablePushState is true when back button is pressed
// undefined otherwise
if (!disablePushState)
history.pushState({ "page": url }, title, url);
...
}
function loadPost(resource, disablePushState) {
// Loads post data through AJAX using a custom function
loadHTML(resource, function (responseText) {
updatePage(responseText, disablePushState);
});
}
...
window.addEventListener('popstate', function (e) {
if (e.state == null || e.state.page == domain) {
window.location = domain;
}
else {
loadPost(e.state.page + '.json', true);
}
return true;
});
希望获得帮助.
这篇关于HTML5历史记录API:不能多次向后退的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!