在工作中碰到一个需求:点击浏览器的后退按钮时,需要判断当前页面的表单数据是否已保存;如果没保存,就给出提示。但浏览器并没有后退事件,这个项目也没有用什么 MV** 之类的框架或库,用的是 jQuery,于是只能尝试模拟浏览器后退事件。
用的是 H5 中的 pushState 与 popstate,代码如下:
var onBrowserBack = function(callback) {
var userAgent = navigator.userAgent.toLowerCase(),
isSafari = userAgent.indexOf('safari') > -1 && userAgent.indexOf('chrome') < 1,
referrer = document.referrer;
if (window.history && window.history.pushState) {
if (isSafari) {
window.onload = function() {
window.isLoaded = 'isLoaded';
};
}
history.pushState('historyPushState', null, null);
window.onpopstate = function(event) {
history.pushState(null, null, null);
if (window.isLoaded === 'isLoaded') {
window.isLoaded = '';
} else {
if (history.state === 'historyPushState') {
history.forward(); // 自动“前进”一步,否则“前进”按钮可点击
} else {
if (typeof callback === 'function' && callback(event) !== false) {
window.location.href = referrer;
}
}
}
};
}
};
popstate 事件会在用户点击浏览器(Chrome, Firefox, Safari)的“前进”和“后退”按钮时触发,但在 Safari 中还多一种触发的情况 ── load 页面时也会触发,例如由其它页面跳转过来,以及刷新。因此,需要在 Safari 中排除这种情况,代码里用的是浏览器的用户代理来检测 Safari。
调用:
onBrowserBack(function() {
console.log('popstate');
// 自定义跳转到其它链接
window.location.href = 'https://www.baidu.com';
return false;
});
如果要跳转到其它页面,需要用 js 手动跳转。
这种模拟方式的问题在于,没法点击“前进”按钮;并且,“后退”按钮只能回退到前一步,如果再点,就又回到了当前页面(使用了 onBrowserBack 的页面)。