Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS-window.history-删除状态_Javascript_Html_Browser History - Fatal编程技术网

Javascript JS-window.history-删除状态

Javascript JS-window.history-删除状态,javascript,html,browser-history,Javascript,Html,Browser History,使用html5window.historyAPI,我可以在我的web应用程序上很好地控制导航 该应用程序目前有两种状态:selectDate(1)和enterDetails(2) 当应用程序加载时,我replaceState并设置popState侦听器: history.replaceState({stage:"selectDate",...},...); window.onpopstate = function(event) { that.toStage(event.state.sta

使用html5
window.history
API,我可以在我的web应用程序上很好地控制导航

该应用程序目前有两种状态:
selectDate
(1)和
enterDetails
(2)

当应用程序加载时,我
replaceState
并设置
popState
侦听器:

history.replaceState({stage:"selectDate",...},...);
window.onpopstate = function(event) {
    that.toStage(event.state.stage);
};
选择日期后,应用程序移动到第2阶段,我将状态2推到堆栈上:

history.pushState({stage:"enterDetails",...},...);
此状态将在详细信息更改时被替换,以便保存在历史记录中

离开第2阶段有三种方式:

  • 保存(ajax提交)
  • 取消
  • 后退按钮
后退按钮由
popstate
侦听器处理。cancel(取消)按钮按下stage 1(阶段1),以便用户可以返回到输入back(返回)按钮的详细信息。这两种方法都很有效

保存按钮应返回到第1阶段,不允许用户导航回详细信息页面(因为他们已经提交)。基本上,y它应该使历史堆栈的长度为1

但是似乎没有
history.delete()
,或者
history.merge()
。我能做的最好的事情就是
history.replaceState(stage1)
,它将历史堆栈保留为:
[“selectDate”,“selectDate”]

我如何去掉一层

编辑:

想了些别的,但也没用

history.back(); //moves history to the correct position
location.href = "#foo"; // successfully removes ability to go 'forward', 
                       // but also adds another layer to the history stack
这将历史堆栈保留为
[“selectDate”,“selectDate#foo”]


那么,作为替代方案,有没有一种方法可以在不推动新状态的情况下删除“前进”历史?

您现在可能已经前进了,但是。。。据我所知,没有办法删除历史记录条目(或状态)

我一直在研究的一个选项是自己用JavaScript处理历史记录,并使用
窗口.history
对象作为排序的载体

基本上,当页面第一次加载时,您可以创建自定义历史对象(这里我们使用一个数组,但根据您的情况使用任何有意义的方法),然后执行初始的
pushState
。我会将您的自定义历史对象作为状态对象传递,因为如果您还需要处理用户离开应用程序并稍后返回,它可能会很有用

var myHistory = [];

function pageLoad() {
    window.history.pushState(myHistory, "<name>", "<url>");

    //Load page data.
}
当用户向后导航时,他们将到达您的“基本”状态(您的状态对象将为null),您可以根据自定义历史对象处理导航。然后,你做另一个pushState

function on_popState() {
    // Note that some browsers fire popState on initial load,
    // so you should check your state object and handle things accordingly.
    // (I did not do that in these examples!)

    if (myHistory.length > 0) {
        var pg = myHistory.pop();
        window.history.pushState(myHistory, "<name>", "<url>");

        //Load page data for "pg".
    } else {
        //No "history" - let them exit or keep them in the app.
    }
}
_popState()上的函数{ //注意,一些浏览器在初始加载时触发popState, //因此,您应该检查state对象并相应地处理事情。 //(在这些示例中,我没有这样做!) 如果(myHistory.length>0){ var pg=myHistory.pop(); window.history.pushState(myHistory,“,”); //加载“pg”的页面数据。 }否则{ //没有“历史记录”-让它们退出或保留在应用程序中。 } } 用户将永远无法使用浏览器按钮向前导航,因为它们始终位于最新页面上

从浏览器的角度来看,每次它们“返回”时,都会立即再次向前推进

从用户的角度来看,他们能够向后浏览页面,但不能向前浏览(基本上模拟智能手机的“页面堆栈”模型)

从开发人员的角度来看,您现在可以高度控制用户在应用程序中的导航方式,同时仍然允许他们使用浏览器上熟悉的导航按钮。您可以随意在历史记录链中的任何位置添加/删除项目。如果在历史记录数组中使用对象,还可以跟踪有关页面的额外信息(如字段内容等)

如果您需要处理用户启动的导航(如用户在基于哈希的导航方案中更改URL),那么您可以使用稍微不同的方法,如

var myHistory = [];

function pageLoad() {
    // When the user first hits your page...
    // Check the state to see what's going on.

    if (window.history.state === null) {
        // If the state is null, this is a NEW navigation,
        //    the user has navigated to your page directly (not using back/forward).

        // First we establish a "back" page to catch backward navigation.
        window.history.replaceState(
            { isBackPage: true },
            "<back>",
            "<back>"
        );

        // Then push an "app" page on top of that - this is where the user will sit.
        // (As browsers vary, it might be safer to put this in a short setTimeout).
        window.history.pushState(
            { isBackPage: false },
            "<name>",
            "<url>"
        );

        // We also need to start our history tracking.
        myHistory.push("<whatever>");

        return;
    }

    // If the state is NOT null, then the user is returning to our app via history navigation.

    // (Load up the page based on the last entry of myHistory here)

    if (window.history.state.isBackPage) {
        // If the user came into our app via the back page,
        //     you can either push them forward one more step or just use pushState as above.

        window.history.go(1);
        // or window.history.pushState({ isBackPage: false }, "<name>", "<url>");
    }

    setTimeout(function() {
        // Add our popstate event listener - doing it here should remove
        //     the issue of dealing with the browser firing it on initial page load.
        window.addEventListener("popstate", on_popstate);
    }, 100);
}

function on_popstate(e) {
    if (e.state === null) {
        // If there's no state at all, then the user must have navigated to a new hash.

        // <Look at what they've done, maybe by reading the hash from the URL>
        // <Change/load the new page and push it onto the myHistory stack>
        // <Alternatively, ignore their navigation attempt by NOT loading anything new or adding to myHistory>

        // Undo what they've done (as far as navigation) by kicking them backwards to the "app" page
        window.history.go(-1);

        // Optionally, you can throw another replaceState in here, e.g. if you want to change the visible URL.
        // This would also prevent them from using the "forward" button to return to the new hash.
        window.history.replaceState(
            { isBackPage: false },
            "<new name>",
            "<new url>"
        );
    } else {
        if (e.state.isBackPage) {
            // If there is state and it's the 'back' page...

            if (myHistory.length > 0) {
                // Pull/load the page from our custom history...
                var pg = myHistory.pop();
                // <load/render/whatever>

                // And push them to our "app" page again
                window.history.pushState(
                    { isBackPage: false },
                    "<name>",
                    "<url>"
                );
            } else {
                // No more history - let them exit or keep them in the app.
            }
        }

        // Implied 'else' here - if there is state and it's NOT the 'back' page
        //     then we can ignore it since we're already on the page we want.
        //     (This is the case when we push the user back with window.history.go(-1) above)
    }
}
var myHistory=[];
函数pageLoad(){
//当用户第一次点击您的页面时。。。
//检查状态以了解发生了什么。
if(window.history.state===null){
//如果状态为空,则这是一个新的导航,
//用户已直接导航到您的页面(不使用后退/前进)。
//首先,我们建立一个“back”页面来捕获向后导航。
window.history.replaceState(
{isBackPage:true},
"",
""
);
//然后在上面推一个“应用”页面——这是用户将坐的地方。
//(随着浏览器的变化,将其置于较短的setTimeout中可能更安全)。
window.history.pushState(
{isBackPage:false},
"",
""
);
//我们还需要开始我们的历史跟踪。
myHistory.push(“”);
返回;
}
//如果状态不为空,则用户将通过历史导航返回到我们的应用程序。
//(根据此处myHistory的最后一个条目加载页面)
if(window.history.state.isBackPage){
//如果用户通过主页进入我们的应用程序,
//您可以将它们向前推进一步,也可以如上所述使用pushState。
窗口。历史。go(1);
//或者window.history.pushState({isBackPage:false},“,”);
}
setTimeout(函数(){
//添加我们的popstate事件侦听器-在此处执行此操作应删除
//处理浏览器在初始页面加载时触发它的问题。
addEventListener(“popstate”,在_popstate上);
}, 100);
}
_popstate(e)上的函数{
如果(e.state===null){
//如果根本没有状态,那么用户必须导航到新的哈希。

//无法删除或读取过去的历史记录

您可以尝试在自己的内存中模拟历史,并在每次发出窗口
popstate
事件时调用
history.pushState
(建议在
var myHistory = [];

function pageLoad() {
    // When the user first hits your page...
    // Check the state to see what's going on.

    if (window.history.state === null) {
        // If the state is null, this is a NEW navigation,
        //    the user has navigated to your page directly (not using back/forward).

        // First we establish a "back" page to catch backward navigation.
        window.history.replaceState(
            { isBackPage: true },
            "<back>",
            "<back>"
        );

        // Then push an "app" page on top of that - this is where the user will sit.
        // (As browsers vary, it might be safer to put this in a short setTimeout).
        window.history.pushState(
            { isBackPage: false },
            "<name>",
            "<url>"
        );

        // We also need to start our history tracking.
        myHistory.push("<whatever>");

        return;
    }

    // If the state is NOT null, then the user is returning to our app via history navigation.

    // (Load up the page based on the last entry of myHistory here)

    if (window.history.state.isBackPage) {
        // If the user came into our app via the back page,
        //     you can either push them forward one more step or just use pushState as above.

        window.history.go(1);
        // or window.history.pushState({ isBackPage: false }, "<name>", "<url>");
    }

    setTimeout(function() {
        // Add our popstate event listener - doing it here should remove
        //     the issue of dealing with the browser firing it on initial page load.
        window.addEventListener("popstate", on_popstate);
    }, 100);
}

function on_popstate(e) {
    if (e.state === null) {
        // If there's no state at all, then the user must have navigated to a new hash.

        // <Look at what they've done, maybe by reading the hash from the URL>
        // <Change/load the new page and push it onto the myHistory stack>
        // <Alternatively, ignore their navigation attempt by NOT loading anything new or adding to myHistory>

        // Undo what they've done (as far as navigation) by kicking them backwards to the "app" page
        window.history.go(-1);

        // Optionally, you can throw another replaceState in here, e.g. if you want to change the visible URL.
        // This would also prevent them from using the "forward" button to return to the new hash.
        window.history.replaceState(
            { isBackPage: false },
            "<new name>",
            "<new url>"
        );
    } else {
        if (e.state.isBackPage) {
            // If there is state and it's the 'back' page...

            if (myHistory.length > 0) {
                // Pull/load the page from our custom history...
                var pg = myHistory.pop();
                // <load/render/whatever>

                // And push them to our "app" page again
                window.history.pushState(
                    { isBackPage: false },
                    "<name>",
                    "<url>"
                );
            } else {
                // No more history - let them exit or keep them in the app.
            }
        }

        // Implied 'else' here - if there is state and it's NOT the 'back' page
        //     then we can ignore it since we're already on the page we want.
        //     (This is the case when we push the user back with window.history.go(-1) above)
    }
}