移动端 h5 实现 webview 退出时弹窗
在移动端开发时,一个很常见的情况是客户端开启一个 WebView 来展示 h5 页面,端上会给这个 WebView 提供一个返回按钮等功能,当点按返回没有历史记录时,就会退出当前 WebView。PM 有时会有需求在退出 h5 应用时弹窗提示用户,在用户点击确认后,才真正退出,这里提供一个实现这个需求的思路。
难点
实现这个方案最大的难点,在于 h5 不能正确知道 WebView 被关闭了。即便知道,也没有办法阻止 WebView 关闭。
解决这个问题的一个最正常的方案,当然是让端上同学给我们加个端能力来调用,但是端开发需要周期,且需要发新版本才能支持,往往不能满足要求。那么还有什么其他方案呢?
解决方案
利用前端 router,我们可以在每次页面打开时,先 replace 进入到一个 base 页面,之后再 push 进入到首页。这样在浏览器历史记录里第一个页面变成了 base。这样用户不断点返回,在退出 WebView 之前,会先进入到 base 页面。只要进入 base 页面,我们就 push 到首页,从而使得一直有浏览记录,阻止了 WebView 的退出。
这个解决方案目前仅在手机百度app中进行过测试,不保证兼容性,只是提供一个思路。
实现
简单实现代码为:
1 | import router from './router.js'; |
这里为了简单我们使用了上次实现的简易 router。
为了防止跟其他hash值冲突,这里我们随机生成了一个 basePath
,任何页面进来,如果时首页,都先 replace 到 basePath
:router.replace('/' + basePath);
。
这里有个要注意的事项,就是如果我们是第一次加载页面,使用window.location.hash = path;
方式修改hash,是不能留下历史记录的,猜测浏览器做了特殊处理。因此需要延迟一定时间再返回首页。
如果不是第一次打开时进入的 basePath
,那么可以调用 init
时传入的回调函数,我们可以在这个回调函数里添加打开弹窗等逻辑。
如何退出?
别的端能力可以没有,但是关闭 WebView 总归会有端能力吧 😓。
好吧,如果没有,我们可以再加一个参数,设置要退出的标记 shouldExit = 1
,basePath
中判断shouldExit === 1
时,不再执行push()
,而是执行一次back()
。我这里就直接调用关闭 WebView 端能力了~
最后还是要强调一下这个方法只在我厂的 app 中使用过,其他 app 不保证可用👻。