HTML5历史记录API:不能多次向后退 [英] HTML5 history API: cannot go backwards more than once

查看:80
本文介绍了HTML5历史记录API:不能多次向后退的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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)事件更好,您可以在loadPostupdatePage函数中添加参数,以防止不必要的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆