微信浏览器中禁用后退按钮并弹窗

微信浏览器中禁用后退按钮并弹窗

最近在做项目的时候,有一个需求是当用户点击微信浏览器自带的后退按钮时,阻止浏览器自带的后退操作,并弹窗让用户自己选择是否后退。下面来看具体的解决方案。

解决方法

从原理上来说,我们是无法阻止浏览器的后退操作的,包括使用event.preventDefault()。所以我们只能换一种思路,浏览器后退操作其实就是从历史记录栈中pop一个元素。所以,只要我们在进入应用的时候多push一个记录,这样当浏览器后退的时候pop的就是我们之前push的元素,从而达到保持当前的history state的目的,再通过监听popstate事件,进行我们需要的一系列操作。

代码
pushHistory () {
  let state = {
    title: '',
    url: window.location.href
  };
  window.history.pushState(state, state.title, state.url);
}

首先是pushHistory,这个方式主要使用了浏览器中history的pushState方法,往state栈中push了一个新的state。

windowListener () {
  let that = this
  this.$vux.confirm.show({
    title: '提示',
    content: '确定要放弃此次编辑?',
    onCancel () {
      that.pushHistory()
    },
    onConfirm () {
      window.history.back()
      that.replace('/demo/mine')
    }
  })
 },

接下来是listener方法,当监听到state变化的时候,进行弹窗,用户点击取消时,再次使用pushHistory方法push一个state,这样就可以实现禁用后退按钮功能,确定的时候要使用一个window.history.back(),原因是发现使用replace跳转出去后会存在一个空的state,导致后退按钮点两次才会生效,所以使用hisotry.back()方法后退一次,将空的state清除,这样state栈就是正常的了。

mounted () {
  this.pushHistory()
  window.addEventListener('popstate', this.windowListener, false)
},
beforeDestroy () {
  window.removeEventListener('popstate', this.windowListener)
}

最后就是在mounted中对popstate的监听和beforeDestroy中的解绑。