当我按下向后或向前按钮并且popstate事件触发时,我可以获得前一状态的状态对象吗?因为不是e.state提供的状态对象,而是我刚刚退回/转发的状态对象?
或者,我可以检测它是按下的后退还是前进按钮?
我需要这个因为我有多个子系统都需要同时使用js历史记录,我当然可以在推送时保存所有这些状态,但是当我弹出时我必须将状态恢复到所有这些都是不受欢迎的,因为它重置了我不需要的对象。例如
state 1 = {a:1, b:1, c:1}
push a = 2
state 2 = {a:2, b:1, c:1}
hit back button, popstate fires state 1 to me
restart a with 1, b with 1, c with 1 while I only need to restart a
另类幻想解决方案
....
hit back button, popstate fires state 1 to me
I also get state 2 (the one I just moved away from) through some black magic
do a differential comparison between the 2 states, find out that I only need to modify a
restart a with 1
编辑:哦,还有,澄清一下,没有简单的方法可以检查页面上当前的状态a,b和c(因为它比abc和123更复杂)
答案 0 :(得分:3)
onpopstate
被触发,因此您无法获得原始状态,但您可以反过来执行此操作,例如获取状态副本和当前状态指示符,并更新您的副本手动onpopstate
。
答案 1 :(得分:1)
答案是装饰pushState
以便在应用程序中记录当前状态。因此,类似:
var app = {
currentState: false,
originalPushState: false,
pushState : function(state, title, href) {
app.currentState = state;
app.originalPushState.call(history, state, title, href);
},
onPopstate : function(event) {
var newState = event.state;
var oldState = app.currentState;
app.currentState = newState;
// you now have the current state and the state you came from
},
init : function() {
window.onpopstate = app.onPopstate;
app.originalPushState = history.pushState;
history.pushState = app.pushState;
}
}
app.init();
顺便说一句,popstate
非常令人困惑。当您弹出一个常规数组时,您将获得弹出的值,而不是现在其末尾的值,因此从语义上来说,这有点奇怪。此外,history.state
始终包含当前状态,因此event.state
是多余的。如果某些event.popped
指向实际弹出的页面状态的指针(也许只有与您的网站位于同一域的指针可用),设计人员的奇怪选择会更明智。>
答案 2 :(得分:0)
这是我的资源,您可以从https://gist.github.com/HasanDelibas/12050fc59d675181ea973d21f882081a看到完整的资源
此库包含:
state
必须是history.pushState( **state**, ...)
的对象(function(){
let stateSymbol = "__state__index__";
history.stateIndex =-1;
history.states=[];
let pushState = history.pushState;
function add(data,title,url){
if(data==null) data={};
if(typeof data!="object") data={data:data};
data[stateSymbol] = (history.stateIndex+1);
history.states.splice(history.stateIndex+1,0,[data,title,url])
history.states.splice(history.stateIndex+2)
history.stateIndex++;
}
history.pushState =function(data,title,url=null){
add(data,title,url);
pushState.bind(history)(data,title,url);
}
addEventListener("popstate",function(e){
var eventObject= {};
var newStateIndex = e.state!=null ? e.state[stateSymbol] : -1;
eventObject.from = history.states[history.stateIndex];
eventObject.to = newStateIndex>-1 ? history.states[newStateIndex] : null;
eventObject.side = history.stateIndex>newStateIndex ? "back" : "forward";
if( newStateIndex > -1 && !(newStateIndex in history.states) ){
add(history.state,"",window.location.href);
}
window.dispatchEvent(new CustomEvent("historyChange", {detail: eventObject} ))
history.stateIndex = e.state!=null ? e.state[stateSymbol] : -1;
});
})();
现在,您可以使用history.states
对象获取所有状态,
并使用addEventListener("popstate",function(e))
使用
/**
* @param e.detail.from [data,title,url]
* @param e.detail.to [data,title,url]
* @param e.detail.side "back" | "forward"
*/
addEventListener("historyChange",function(e){
var from = e.detail.from; // [ data , title , url ]
var to = e.detail.to; // [ data , title , url ]
var side = e.detail.side; // "back" | "forward"
console.log( `You changed history. Side is ${e.detail.side}.\nFrom:${e.detail.from[2]}\nTo:${e.detail.to[2]}`)
})
history.pushState("1", "DENEME-TEST" ,"?1");
history.pushState("2", "DENEME-TEST" ,"?2");
// list of history states
console.log( history.states )
/*
[
[ {...} , "DENEME-TEST" ,"?1" ]
[ {...} , "DENEME-TEST" ,"?2" ]
]
*/
// get history current state index
console.log( history.stateIndex )
/*
1
*/