移动端监听物理返回

业务场景:

用户没有填完数据却不小心点到了回退按钮,此时需要展示确认弹框

项目场景:

vue2 + uni-app + Chrome Dev调试工具

代码片段:

onLoad(options){
        // 将当前url地址添加到浏览器的历史记录中
        window.history.pushState(null, null, document.URL);//第三个参数不写默认为当前url地址
        // 监听物理返回
        window.addEventListener('popstate', this.listenBack, false);
}

destroyed(){ //也可用 beforeDestroy 、onUnload 代替
        // 页面销毁前取消上一次的监听
        window.removeEventListener('popstate', this.listenBack, false);
},

methods:{
        // 物理返回的操作函数
        listenBack() {
            // 此处state仅作参考
            if (this.state === '未保存') {
                uni.showModal({
                    title: '提示',
                    content: '内容还未保存,是否退出',
                    success: (res) => {
                        if (res.confirm) {
                            console.log('用户点击确定');
                            //此处可写人一些用于保存页面信息的代码……
                            //因为在onLoad中中多存储了一个历史记录,所以这里要返回上上个页面
                            history.go(-2);
                        } else if (res.cancel) {
                            console.log('用户点击取消');
                            //等待用户接着操作……
                        }
                    }
                });
            }else{
                history.go(-2)
            }
        }
}

思路分析:

其实这个需求的难点在于:监听到了物理返回,但是会先执行当前vue页面的destroyed函数再执行物理返回中的操作函数。这样就会导致页面已经跳回上一个页面后才出现提示框。

于是我的做法是:在当前vue页面(A页面)加载时往浏览器历史里备份一份当前的url地址(B页面),此时用户点击返回,就会从B页面跳到A页面,由于这两个页面地址一致,就会产生点击回退却没有效果的错觉。接着回到A页面后,触发监听事件,处理具体的业务流程……

其他方法:

1.如果不需要监听物理返回,而是监听uni-app自带的左上角的返回键。可以使用uni的生命周期函数 onBackPress

2.除了onpopstate可以监听页面回退外,还可以使用window.onhashchange监听hash路由变化。

3.也可以用vue-router中的 beforeRouteLeave 监听路由变化。但是我项目中使用没生效,就没用这种方法。

无用的小技巧:

如果想禁用一个页面的返回操作,只需要在这个页面的历史记录中写入大量的历史。比如:

for(var i = 0 ; i < 20 ; i++){
    history.pushState(null,null)
}

相对的,取消禁用就需要以下代码 + 一个手动回退

history.go(-20)
location.reload()

参考文献:

1.pushState 用法 - MDN

2.H5物理返回键处理逻辑梳理

猜你喜欢

转载自blog.csdn.net/A_Common_Man/article/details/129233562