H5监听重写Android返回键

2,617 阅读2分钟

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() 来清除之前添加的函数和历史记录。。。。