模拟浏览器后退事件
在工作中碰到一个需求:点击浏览器的后退按钮时,需要判断当前页面的表单数据是否已保存;如果没保存,就给出提示。但浏览器并没有后退事件,这个项目也没有用什么 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 的页面)。