Android物理返回键的点击事件,一般webview的默认行为是 **window.history.go(-1)** ,但是在实际需求场景下,简单的页面回退并不能满足需求,所以需要H5页面监听Android物理返回键从而自定义处理方法。
实现代码
// AndroidBack.js(function (pkg) {
// 维护处理方法的栈
var _android_back_handles = [];
// 触发一次popstate方法,则调用最新处理方法
var handlePopstate = function () {
var handle = _android_back_handles.pop();
handle && handle();
};
// 通过调用listen方法添加处理方法
var listen = function (handle) {
_android_back_handles.push(handle);
};
// 通过调用push方法,新增一条历史记录,并添加对应处理方法
var push = function (state, handle) {
if (handle) {
// 添加一条历史记录,不刷新页面
history.pushState(state, null, location.href);
handle && _android_back_handles.push(handle);
}
};
// 通过调用remove方法,删除处理方法,并调用hsitory.back()来清除一条历史记录。
var remove = function () {
_android_back_handles.pop();
window.history.back();
};
const init = function () {
// 监听 popstate 事件,当点击Android物理返回键时,会触发该事件
window.addEventListener('popstate', handlePopstate);
this.listen = listen;
this.push = push;
this.remove = remove;
};
init.call(window[pkg] = window[pkg] || {});
})('AndroidBack');
使用方式
// 监听Android物理返回键,自定义处理方法
window.AndroidBack.listen(() => {
console.log('back');
});
// 新增Android物理返回键监听事件,使用场景,比如:页面内弹出浮层,点击Android物理返回键,不是回退页面,而是关闭浮层
window.AndroidBack.push('close_modal', () => {
// 关闭弹窗
console.log('close_modal');
});
// 删除添加的处理方法并且调用history.back()删除历史记录。
window.AndroidBack.remove()
实现原理
HTML5 新API
history.pushState(state, title, url); 添加一条历史记录,不刷新页面
事件
popState事件:历史记录发生变化时触发,调用history.pushState()或history.replaceState()不会触发此事件
window.addEventListener('popstate', handlePopstate);
window.addEventListener('hashchange', handleHashChange);
场景
在安卓手机的H5页面中,调出弹出框的时候,执行以下代码:
window.AndroidBack.push('close_modal', () => {
// 关闭弹窗
console.log('close_modal');
});
其中的作用是添加一条历史记录到history中,并且不会刷新页面,当用户点击安卓机的返回键时,此段代码 window.addEventListener('popstate', handlePopstate) 会捕获安卓的返回键事件,并且执行 console.log('close_modal') 方法体,并且会跳到前面添加的一条历史记录(history.pushState(state, null, location.href)),但是不会刷新界面。
最后的效果就是可以关闭弹框并且禁止返回上一个页面。。。。
当用户点击弹框关闭按钮时,需使用 window.AndroidBack.remove() 来清除之前添加的函数和历史记录。。。。