最近使用uniapp开发一个h5端的应用,由于首次使用,着实踩了不少坑,阻止用户回退就是其中的一个。
先上结论:只要在不希望被回退到的页面里(例如登录页)在跳转之前使用history.replaceState方法把这一页的history的地址替换成跳转后的页面地址,就不会再回退到这一页了,因为历史页面地址变成了跳转后页面地址。
这个需求比较常见,比如:用户从登录页面登录成功后不希望用户能够回退到登录页,用户支付成功后不希望用户回退到支付页。以前做电脑端的项目还不怎么注意这些,毕竟很少会用到浏览器的回退键。但是在手机上用户会频繁的使用回退,比如从微信公众号内点击模板消息进入网页应用后,虽然页面左上角会有×按钮直接关闭,但是很多人单手握持手机时可能更习惯使用手机回退键或者全面屏手势侧滑回退(相当于手机回退键),直至退出网页应用,这就导致可能会回退到登录页或者其他不太想让用户回退的页面。
最开始解决这个问题时,首先想到的是监听返回事件,uniapp有onBackPress方法:
但是后来发现h5端无法只支持顶部导航栏按钮的监听,手机和浏览器的回退并不支持。
经过多方查阅后,发现可以监听popstate事件:
onShow() {
var state = {
title: "title",
url: "#"
};
history.pushState(state, "title", document.URL);
window.addEventListener('popstate', this.handleback);
},
onUnload(){
setTimeout(() => {
window.removeEventListener('popstate', this.handleback);
},300)
},
onHide() {
window.removeEventListener('popstate', this.handleback);
},
methods: {
handleback(){
var vm = this;
var myback = function(){
var state = {
title: "title",
url: "#"
};
history.pushState(state, "title", document.URL);
}.bind(vm)
uni.showModal({
title: '已经在首页了!',
showCancel:false,
success: myback
})
}
}
但是在使用后发现:虽然在控制台使用history.go(-1)这样的方式可以触发事件,但是使用浏览器回退键以及手机的回退键某些时候并不会触发事件,用起来体验不是很好。
在监听回退事件这里纠结了很久以后,突然想到history除了有pushState方法,还有个replaceState方法,那么我只要在不希望被回退的页面里把history信息替换成首页不就不会再回退回来了吗?于是我在登录页登录成功跳转语句之前加入
window.history.replaceState(null,null,'/')
然后再跳转到首页,这样再回退就不会回到登录页了,支付页同理。
至此,问题解决!