您如何确定地检测用户是否在浏览器中按下了后退按钮?
如何使用#URL系统在单页web应用程序中强制使用页面内返回按钮?
为什么浏览器的后退按钮不触发它们自己的事件!?
您如何确定地检测用户是否在浏览器中按下了后退按钮?
如何使用#URL系统在单页web应用程序中强制使用页面内返回按钮?
为什么浏览器的后退按钮不触发它们自己的事件!?
当前回答
正确答案已经在那里了。我想提一下新的JavaScript API PerformanceNavigationTiming,它取代了过时的performance。navigation。
下面的代码将登录控制台“back_forward”如果用户登陆到您的页面使用后退或前进按钮。在项目中使用兼容性表之前,请先查看兼容性表。
var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
console.log(perfEntries[i].type);
}
其他回答
在javascript中,导航类型2意味着浏览器的后退或前进按钮被点击,浏览器实际上是从缓存中获取内容。
if(performance.navigation.type == 2)
{
//Do your code here
}
我已经为这个需求挣扎了很长一段时间,并采用了上面的一些解决方案来实现它。然而,我偶然发现,它似乎可以在Chrome、Firefox和Safari浏览器以及Android和iPhone上运行
页面加载:
window.history.pushState({page: 1}, "", "");
window.onpopstate = function(event) {
// "event" object seems to contain value only when the back button is clicked
// and if the pop state event fires due to clicks on a button
// or a link it comes up as "undefined"
if(event){
// Code to handle back button or prevent from navigation
}
else{
// Continue user action through link or button
}
}
如果有帮助请告诉我。如果我错过了什么,我会很高兴去理解。
只有重新定义API(更改对象' history '的方法),才能实现成熟的组件。 我将分享刚才写的课程。 在Chrome和Mozilla上测试 仅支持HTML5和ECMAScript5-6
class HistoryNavigation {
static init()
{
if(HistoryNavigation.is_init===true){
return;
}
HistoryNavigation.is_init=true;
let history_stack=[];
let n=0;
let current_state={timestamp:Date.now()+n};
n++;
let init_HNState;
if(history.state!==null){
current_state=history.state.HNState;
history_stack=history.state.HNState.history_stack;
init_HNState=history.state.HNState;
} else {
init_HNState={timestamp:current_state.timestamp,history_stack};
}
let listenerPushState=function(params){
params=Object.assign({state:null},params);
params.state=params.state!==null?Object.assign({},params.state):{};
let h_state={ timestamp:Date.now()+n};
n++;
let key = history_stack.indexOf(current_state.timestamp);
key=key+1;
history_stack.splice(key);
history_stack.push(h_state.timestamp);
h_state.history_stack=history_stack;
params.state.HNState=h_state;
current_state=h_state;
return params;
};
let listenerReplaceState=function(params){
params=Object.assign({state:null},params);
params.state=params.state!==null?Object.assign({},params.state):null;
let h_state=Object.assign({},current_state);
h_state.history_stack=history_stack;
params.state.HNState=h_state;
return params;
};
let desc=Object.getOwnPropertyDescriptors(History.prototype);
delete desc.constructor;
Object.defineProperties(History.prototype,{
replaceState:Object.assign({},desc.replaceState,{
value:function(state,title,url){
let params={state,title,url};
HistoryNavigation.dispatchEvent('history.state.replace',params);
params=Object.assign({state,title,url},params);
params=listenerReplaceState(params);
desc.replaceState.value.call(this,params.state,params.title,params.url);
}
}),
pushState:Object.assign({},desc.pushState,{
value:function(state,title,url){
let params={state,title,url};
HistoryNavigation.dispatchEvent('history.state.push',params);
params=Object.assign({state,title,url},params);
params=listenerPushState(params);
return desc.pushState.value.call(this, params.state, params.title, params.url);
}
})
});
HistoryNavigation.addEventListener('popstate',function(event){
let HNState;
if(event.state==null){
HNState=init_HNState;
} else {
HNState=event.state.HNState;
}
let key_prev=history_stack.indexOf(current_state.timestamp);
let key_state=history_stack.indexOf(HNState.timestamp);
let delta=key_state-key_prev;
let params={delta,event,state:Object.assign({},event.state)};
delete params.state.HNState;
HNState.history_stack=history_stack;
if(event.state!==null){
event.state.HNState=HNState;
}
current_state=HNState;
HistoryNavigation.dispatchEvent('history.go',params);
});
}
static addEventListener(...arg)
{
window.addEventListener(...arg);
}
static removeEventListener(...arg)
{
window.removeEventListener(...arg);
}
static dispatchEvent(event,params)
{
if(!(event instanceof Event)){
event=new Event(event,{cancelable:true});
}
event.params=params;
window.dispatchEvent(event);
};
}
HistoryNavigation.init();
// exemple
HistoryNavigation.addEventListener('popstate',function(event){
console.log('Will not start because they blocked the work');
});
HistoryNavigation.addEventListener('history.go',function(event){
event.params.event.stopImmediatePropagation();// blocked popstate listeners
console.log(event.params);
// back or forward - see event.params.delta
});
HistoryNavigation.addEventListener('history.state.push',function(event){
console.log(event);
});
HistoryNavigation.addEventListener('history.state.replace',function(event){
console.log(event);
});
history.pushState({h:'hello'},'','');
history.pushState({h:'hello2'},'','');
history.pushState({h:'hello3'},'','');
history.back();
```
我的版本:
const inFromBack = performance && performance.getEntriesByType( 'navigation' ).map( nav => nav.type ).includes( 'back_forward' )
看到这个:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
它工作得很好……