博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小tips-一种移动端模拟实现返回拦截的方案
阅读量:5873 次
发布时间:2019-06-19

本文共 2533 字,大约阅读时间需要 8 分钟。

移动端作为互联网重要入口,切图仔前端工程师开发移动端页面早已是司空见惯的事了,并且其中大部分都是内嵌于客户端(app,小程序)的 h5页面,即 webview

有次被同事问到一个问题,他有个需求,是一个内嵌在客户端app内的页面,有个功能点是拦截客户端的返回操作,实现页面内弹层的显示与隐藏,拦截点包括 app页面上自带的返回按钮以及安卓机的物理按钮,类似于下面这种:

点击购物车,则购物车元素从页面底部弹起显示,点击遮罩层,则弹层关闭隐藏,这是很正常的操作,而除此之外,还需要实现的一个功能是,点击屏幕返回键或者安卓机的物理返回键,也能够关闭弹层,并且保证页面不发生跳转

我听了微微一笑,问他,哪个傻叉 PM提的需求?,h5怎么拦截 app甚至是物理按钮的操作?你当时没有怼他吗?客户端那边有提供拦截返回的 sdk接口吗?同事回答 sdk没有提供这个能力,他觉得不好实现,但 PM坚持要做这个功能

于是我抱着反正不是我的需求,我天马行空章口就来瞎提建议也没关系助人为乐的态度思考了一会,谁知还真让我想到了一个方案(我不确定以前是不是在什么地方看到过,总之就是想到了),回来验证了一下,确实是可行的

关键点在于,利用返回操作会触发路由改变的特性来模拟达到拦截的效果,并不是真的监听或者拦截到了屏幕返回键或者物理返回键的点击

路由配置

假设需要进行模拟拦截返回操作的主页面路由为 /physicsBack,其下有个子路由 /physicsBack/footerModal,当路由为 /physicsBack时就只显示页面,当路由为 /physicsBack/footerModal时,就在 /physicsBack上弹起弹层

这里的 /physicsBack/footerModal说起来是子路由,但实际上我们只是想利用其作为路由的一个能力——即拦截返回操作,所以实际上并不真的需要为这个路由配置一个页面,你当然也可以这么做,最后也能实现效果,但未免麻烦了些

这里我将 /physicsBack/physicsBack/footerModal全部指向同一个页面,即主页面,然后通过对路由的监听,来控制弹层的显隐

路由配置如下:

const router = new VueRouter({  routes: [{    path: '/physicsBack/(footerModal)?',    component: physicsBack  }] })复制代码

/physicsBack/(footerModal)?同时匹配 /physicsBack/physicsBack/footerModal,所以无论路由是 /physicsBack 还是 /physicsBack/footerModal,都将指向 physicsBack这个页面,达到即使路由在这两个中来回切换,但页面也毫无变化的目的

路由监听

虽然在路由 /physicsBack/physicsBack/footerModal中切换不会引起页面的切换,自始至终都停留在 physicsBack组件上,但却可以在 physicsBack组件中对路由进行监听,进而根据监听到的路由变化来控制弹层的显隐:

watch: {  $route (to, from) {    this.manageFooterModal(to.path, from.path)  }}// ...manageFooterModal (toPath, fromPath) {  if (toPath === '/physicsBack/footerModal') {    this.visible = true  } else if (fromPath === '/physicsBack/footerModal') {    this.visible = false  }}复制代码

toPath/physicsBack/footerModal,表示将切换到这个路由,前面已经规定了,当路由切换到这个位置时,显示弹层;

fromPath/physicsBack/footerModal,表示从有弹层的页面回退或者跳走,则关闭弹层

这里你不用 watch也是可以的,用 vue-router提供的路由守卫钩子函数(beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave)也能够达到同样的效果,这些钩子函数只是进一步简化了流程,但本质都还是一样的,目的都是实现对路由的监听与控制,所以你哪怕不想依赖于框架提供的能力,通过设置原生监听函数 window.addEventListener('hashchange', callback)window.addEventListener('popstate', callback) 照样可以实现功能

除了通过路由控制之外,页面元素肯定也必须能够对弹层显隐进行控制,例如点击某个元素弹起弹层,这样才贴合真实使用场景

同样的,由于弹层的显隐实际上是由路由的切换控制,所以页面内部想要改变弹层的显隐,也必须通过路由切换来完成:

changeVisible () {  if (this.visible) {    this.$router.go(-1)  } else {    this.$router.push('/physicsBack/footerModal')  }}复制代码

由于这实际上是利用了系统的返回能力,所以无论你在浏览器上还是客户端 appwebview内,无论是使用屏幕返回还是物理返回键,都可以达到同样的效果

实现的效果如下:

做了个 ,感兴趣的可以亲自试下,代码也已经上传到

小结

本文所说的通过路由来模拟拦截返回键的能力,不仅仅可以应用在弹层例子上,其他跟返回相关的操作理论上都可以发挥想象,例如返回重定向,禁止用户退出页面(这是什么傻叉需求啊)

转载于:https://juejin.im/post/5c919cd75188252d5379db69

你可能感兴趣的文章
《Essential Linux Device Drivers》中文版第1章
查看>>
让远程传输大文件变得更快
查看>>
iOS:Xcode7下创建 .a静态库 和 .framework静态库
查看>>
complex的小困惑
查看>>
十进制、十六进制、二进制的转换
查看>>
双网卡centos7 iptables防火墙与/etc/rc.d/rc.local开机运行
查看>>
tomcat PermGen space 不足的解决方法
查看>>
STM32系统滴答_及不可不知的延时技巧 - (上)
查看>>
Linux下企业级分区方案
查看>>
CentOS下LAMP一键yum安装脚本
查看>>
拖来拖去今天终于重装系统了
查看>>
NestJS 脑图
查看>>
我的友情链接
查看>>
Html body的滚动条禁止与启用
查看>>
Tengine新增nginx upstream模块的使用
查看>>
多媒体工具Mediainfo
查看>>
1-小程序
查看>>
CentOS图形界面和命令行切换
查看>>
HTML5通信机制与html5地理信息定位(gps)
查看>>
Mind_Manager_2
查看>>