今天做东西,遇到一个问题,由于流程稍微有些麻烦,需要在页面之间频繁跳转。在页面上放上按钮写监听还可以,但是如果按到物理返回键呢?默认的物理返回键是返回上一页,这样子是让复杂的流程更加复杂,也无法知晓因为复杂的跳转最后会跳到哪里去,更严重点就是引发接口404的问题。

  就因为这个问题,需要更改默认的物理返回键事件。查阅了网上的资料,五花八门,也因为自己对这方面不熟悉,越搞越混乱,最后还是大家一起理顺,找到问题所在。以下是总结一下解决方法,以防以后遇到忘记了:



一. 监听物理回退

1.添加页面监听

  平时的返回只是写个方法,绑定到对应的一个组件上,路由设置好也就跳转,物理返回则不同,需要考虑几个页面之间的交互关系,一个部分搞错,后面有问题都比较难查出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//第一步,添加监听事件,在mount里添加以下代码
mount(){
……
if ( window.history && window.history.pushState ){
history.pushState(null, null, document.URL) //这句话为将当前页面插入history中
window.addEventListener('popstate',this.goTo, false) //不捕捉
}
……
}

//然后在页面销毁的周期加入去除监听
destroyed(){
window.removeEventListener('popstate', this.goTo, false) //这里一定要销毁,否则会出现每次按返回都触发你的自定义跳转
}

//然后是实现你自定义的跳转方法
methods{

goTo(){
uni.reLanch({
url: "/pages/page/home"
})
},

……
}

2.多个页面

  注意,监听物理返回的页面,最好之间不要有直接跳转的关系,否则,很容易出现一些奇奇怪怪的问题,例如:跳转过多,history长度过长导致爆栈;或者弹窗不会弹出来。因为监听的关系很容易导致越跳越乱,如果非得要多个页面监听物理返回的跳转,可以选择跳到同一个页面,如主页……等。

  • 1.如果有弹窗,如:wx(uni).showToast、wx(uni).showModal等,两个有直接关系的页面不要都设置物理返回,否则弹窗会不出来,而你可能又会找不到问题所在。其实是两个监听互相影响了。
  • 2.既然有弹窗,就有多次按多次弹出来的问题,如果你只是confirm的时候跳转,取消的时候不作处理,同样的,按了取消第二次按返回就不会弹出弹窗。即需要在唤出弹窗的前方调用
    history.pushState(null,null,document.URL)
    然后在取消里面做你要的操作。如果将上方语句放在取消里面,则会报爆栈的错误,浏览器会变得很卡。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
methods{
goTo(){
history.pushState(null,null,document.URL);
uni.showModal({
title: "提示",
content: "是否跳回首页?",
confirmText: "是",
cancelText: "否",
success: res=>{
if(res.confirm){
uni.reLanch({
url: "/pages/page/home"
});
else if(res.cancel){
console.log('取消')
}
},
fail: err=>{
console.log(err)
}
});
}
}
//这么设置后,可防止爆栈以及可以实现点了取消之后再点能再次弹框
  • 3.除了上面两种,剩下的就是监听物理返回不回退,保持在本页,如退回到首页后,不能再让其乱回退和乱跳,只能保持在本页中,(其实应该让其关闭,只是没有很好的办法,故只能让留在本页)

    即在自定义返回的方法中加入history.pushState(null,null,document.URL)就可以了。

二. 展开占满全屏

  在网页中,更准确的是移动端中,有一种效果是点了按钮之后,展开的内容占满整个屏幕,且保持可以滑动,收缩之后又返回到页首,返回原样。这种效果虽然只是小意思,但是没接触的话来做可能也会一时摸不着头脑。坑的点主要有以下几个:

  • 展开和滚动同时作用时,什么都不生效,只展开。
  • 设置滚动到某一个容器中,不生效,网上说的滚动到某一个view,针对的是微信小程序,没有尝试过,不知道是否能用。
  • 给容器设置监听滚动到它这个地方,不生效。
  • 自己做处理,麻烦。

  然而,它坑就坑在第一点,按照逻辑是没有错的,但是一直不起作用,怀疑是自己写错,但怎么想也都是对的呀。然后,想想要不加个短短的延迟,即setTimeout()。setInterval()的话好像会引起其他问题。果然,实现了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//写一个自定义的方法

methods{
……
jumpto(e){ //这里的e是组件里传入&event这个内置参数
this.isExpand = !this.isExpand
if(this.isExpand){
setTimeout(()=>{
uni.pageScrollto({ //页面滚动函数
duration: 0, //设为0马上滚动到,大于0有一个下来的中间过程,越长越明显
scrollTop: e.currentTarget.offsetTop
})
},300)
}
else{
setTimeout(()=>{
uni.pageScrollto({
duration: 0,
scrollTop: 0
})
},300)
}
},
……
}

  以上的问题,是在uniapp中遇到,主要还是对前端一些细节的东西没掌握好。但是啊,uniapp还是挺坑的,又要兼容小程序又要兼容h5,有的时候写着写着忘记了或者弄混了,就很容易埋雷,导致结果与自己预期不同。
  不过呀,还是要好好掌握,前端还是有挺多有意思的东西。

本文标题:监听物理回退与展开占满全屏

文章作者:JarryChen

发布时间:2019年11月16日 - 20:08

最后更新: 2019年11月29日 07:15

原始链接: https://jarrychen.xyz/archives/a2145d56.html

× 请我喝奶茶~
打赏二维码