2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 微信H5如何关闭浏览器(如何监听手机的物理返回键)

微信H5如何关闭浏览器(如何监听手机的物理返回键)

时间:2020-01-27 11:39:36

相关推荐

微信H5如何关闭浏览器(如何监听手机的物理返回键)

一、背景

背景是这样的:该项目进入h5时会通过location.replace(xxx) 或 location.href = xxx跳转到某个地址①,该地址会请求获得微信 openId;获取成功后再重定向到h5首页。

那么问题来了,重定向会在微信浏览器留下一条 history 记录,那么我在h5首页按手机的物理返回键,就不会因为已是第一页而退出浏览器,而是跳回地址①,再重定向到首页;按返回键又回到①,又重定向到首页。。。除非手速够快,不然就会形成“死循环”。

那么,怎样能在首页按返回键时,直接关闭微信浏览器呢?

二、解决思路

解决思路很自然:

1、在首页监听手机何时被按下返回键;

2、当发生1中事件时,截停浏览器默认事件(不返回history中的重定向页);

3、然后执行自定义事件(关闭微信浏览器)。

三、解决方法

1、在首页监听手机何时被按下返回键

监听popstate事件。其实并没有严格意义上的“按下物理返回键”事件,但手机的物理返回键其实作用就跟浏览器左上角的 “←” 按钮作用相似,都是返回上一个页面(也就是history中的上一条记录)。而浏览器中返回上一条 history 记录时触发了 “popstate” 事件。因此我们可以利用 “popstate” 来模拟“按下物理返回键” 事件。

代码:

// 本示例使用了 vue3 + typescript。其他框架类似,在组件创建、挂载时加上这个事件监听;function closeWXWindow() {// TODO: 关闭微信浏览器}onMounted(() => {window.addEventListener('popstate', closeWXWindow);});// 记得离开该页面时取消监听,否则在其他页面按返回键也会直接关闭浏览器了~onUnmounted(() => {window.removeEventListener('popstate', closeWXWindow);});

2、当发生1中事件时,截停浏览器默认事件(不返回history中的重定向页)

这个稍微有点小复杂~

大家乍一看可能脱口而出:“这个我熟!在事件处理函数里加一行event.preventDefault()嘛!”

遗憾的是,即使用上这么一行,浏览器还是会回到上一级页面。其实可以这么理解:正是因为返回了上一级页面,所以才会有 "popstate" 事件;而不是有了 “popstate” 事件,然后才去执行返回上一级页面的默认行为。

所以说,按下返回键后,“返回上一级页面” 这个动作,浏览器无论如何都会执行

直接截停是没戏了,但咱们可以模拟呀——只要上一级页面跟当前页面是同一个页面,那返回去跟没返回去不就一样了么!

因此,我们只需要在进入首页(假设地址是 localhost:8080/home)时,往 history 里再加入一条首页记录,不就好了嘛!

代码:

function closeWXWindow() {// TODO: 关闭微信浏览器}onMounted(() => {/** 新增内容 begin👇*/ const state = {title: 'title',url: '#',};// 往 history 里新加了一条 “localhost:8080/home/#” 记录// “#” 其实就是当前页的意思,有这个符号跟没有一样window.history.pushState(state, 'title', '#'); /** 新增内容 end👆*/window.addEventListener('popstate', closeWXWindow);});// 记得离开该页面时取消监听,否则在其他页面按返回键也会直接关闭浏览器了~onUnmounted(() => {window.removeEventListener('popstate', closeWXWindow);});

很棒,现在浏览器还是会返回“上一页”,但“上一页”其实还是首页,所以看起来就是:按返回键并没有返回上一页!目标达成!

3、然后执行自定义事件(关闭微信浏览器)

这个简单!使用微信开放接口WeixinJSBridge即可。

不需要任何引入,直接在代码里使用:

/** 关闭微信浏览器 */function closeWXWindow() {// 微信浏览器里有一个 WeixinJSBridge 对象,就像普通浏览器里必有 window 对象一样,无需额外引入// 不过保险起见,还是判断一下是否为空if (WeixinJSBridge?.invoke) {WeixinJSBridge.invoke('closeWindow', {}, () => {console.error('关闭微信网页失败');});}}

注:1)其他教程里有说用 "WeixinJSBridge.call('closeWindow', () => {...})" 的。但我实测该方法已经无效了。

2)如果项目使用了 ts,那会报WeixinISBridge 未定义的错。记得在 xx.d.ts 文件中定义一下该变量:declare const WeixinJSBridge;

4、完整代码

/** 关闭微信浏览器 */function closeWXWindow() {if (WeixinJSBridge?.invoke) {WeixinJSBridge.invoke('closeWindow', {}, () => {console.error('关闭微信网页失败');});}}// 拦截返回键。在首页返回时,应该直接关闭h5,避免回到重定向页面无限循环onMounted(() => {const state = {title: 'title',url: '#',};window.history.pushState(state, 'title', '#');window.addEventListener('popstate', closeWXWindow);});onUnmounted(() => {window.removeEventListener('popstate', closeWXWindow);});

四、补充

到这里已经完成了!

不过你是否注意到我在“一、背景”的第一行标了一个加粗:location.replace(xxx) 或 location.href = xxx

是这样的,我的这个“首页”其实是指 vue-router 中的首页,不是浏览器history中的首页。如果是要监控 vue-router 中非首页的返回,其实可以不监听popstate 事件,而是用 vue-router 中的onBeforeRouteLeave钩子。该钩子在离开当前路由页前被调用。

代码:

/** 关闭微信浏览器 */function closeWXWindow() {if (WeixinJSBridge?.invoke) {WeixinJSBridge.invoke('closeWindow', {}, () => {console.error('关闭微信网页失败');});}}onBeforeRouteLeave((to, from, next) => {closeWXWindow();next(false); // 阻止下一步操作,看起来就是“不返回上一级页面”});

有不正确之处还望指出~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。