【问题标题】:HTML5 history API: cannot go backwards more than onceHTML5 历史 API:不能多次后退
【发布时间】:2015-05-24 22:51:33
【问题描述】:

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

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

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

这反而有效: 主页 -> 第二页 -> 主页

有人知道我错过了什么吗?

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

【问题讨论】:

    标签: javascript html html5-history


    【解决方案1】:

    当你按下后退按钮时,popstate 事件被触发,loadPost 函数被调用。但是在loadPost 中,再次调用history.pushState 方法,将当前页面再次推入历史堆栈。这就解释了为什么第一个后退按钮有效,然后又无效。

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

    if (!history.state || history.state.page!=url)
        history.pushState({ "page": url }, title, url);
    

    2) 事件更好,可以给loadPostupdatePage函数添加参数,防止不必要的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;
        });
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      相关资源
      最近更新 更多