Javascript HTML5历史API:不能倒退多次

Javascript HTML5历史API:不能倒退多次,javascript,html,html5-history,Javascript,Html,Html5 History,我一直在尝试让我的脚本正常工作,但显然它有问题:当我尝试使用“浏览器后退”按钮后退时,它会在第一页后退时停止,即第二次单击“后退”按钮时,无法正常工作,反而会自动更新当前页 示例: 主页->第二页->第三页->第二页->第二页->第二页(依此类推) 首页->第二页->第三页->第四页->第三页->第三页(依此类推) 相反,这是可行的: 主页->第二页->主页 有人知道我遗漏了什么吗 var domain = 'http://example.com/'; function updatePage(

我一直在尝试让我的脚本正常工作,但显然它有问题:当我尝试使用“浏览器后退”按钮后退时,它会在第一页后退时停止,即第二次单击“后退”按钮时,无法正常工作,反而会自动更新当前页

示例: 主页->第二页->第三页->第二页->第二页->第二页(依此类推)

首页->第二页->第三页->第四页->第三页->第三页(依此类推)

相反,这是可行的: 主页->第二页->主页

有人知道我遗漏了什么吗

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);
})();
var域=http://example.com/';
函数updatePage(json){
var postData=JSON.parse(JSON);
//pushState
var url=domain+postData.url;
var title=postData.title;
document.title=标题;
pushState({“page”:url},标题,url);
//清除某些元素并用新内容填充它们
// ...
//创建一个“a”元素,为下一篇文章触发AJAX
var a=document.createElement('a');
a、 innerHTML=postData.next;
a、 href=domain+postData.next;
document.getElementById('container').appendChild(a);
李斯特(a);
//创建另一个“a”元素,用于触发上一篇文章的AJAX
a=document.createElement('a');
a、 innerHTML=postData.previous;
a、 href=domain+postData.previous;
document.getElementById('container').appendChild(a);
李斯特(a);
}
函数loadPost(资源){
//使用自定义函数通过AJAX加载post数据
loadHTML(资源,函数(){
updatePage(this.responseText);
});
}
函数listenerAttacher(元素){
//向元素添加单击侦听器。
元素。addEventListener('click',函数(e){
e、 预防默认值();
e、 停止传播();
loadPost(this.href+'.json');
返回false;
}, 
假);
}
(功能(){
replaceState({'page':window.location.href},null,window.location.href);
//将事件侦听器添加到所有需要它的元素。
var titles=document.querySelectorAll(“.post title”);
对于(变量i=0;i
当您按下后退按钮时,
popstate
事件被触发,并调用
loadPost
函数。但是,在
loadPost
中,再次调用
history.pushState
方法,该方法将再次将当前页面推送到历史堆栈上。这就解释了为什么第一个后退按钮起作用,然后又不起作用

1) 快速修复方法是检查当前状态是否与您尝试推送的状态匹配:

if (!history.state || history.state.page!=url)
    history.pushState({ "page": url }, title, url);
2) 事件更好,您可以向
loadPost
updatePage
函数添加参数,以防止不必要的
pushState
调用:

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;
    });

希望有此帮助。

当您按下后退按钮时,
popstate
事件被触发,并且调用了
loadPost
函数。但是,在
loadPost
中,再次调用
history.pushState
方法,该方法将再次将当前页面推送到历史堆栈上。这就解释了为什么第一个后退按钮起作用,然后又不起作用

1) 快速修复方法是检查当前状态是否与您尝试推送的状态匹配:

if (!history.state || history.state.page!=url)
    history.pushState({ "page": url }, title, url);
2) 事件更好,您可以向
loadPost
updatePage
函数添加参数,以防止不必要的
pushState
调用:

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;
    });
希望这有帮助