Safari浏览器执行history.back()无效,其他端并没有出现该问题,如何解决?

使用场景:用户回退挽留自定义弹窗
开发环境:vite4.1.4、vue3.2.47、router4.1.6
封装的工具类:

export function handleBrowserGoBack(backCallBack) {
    // 保存初始历史记录长度
    pushHistory();
    addPopstateListener(backCallBack);
}

/**
 * 向历史记录中插入了当前页
 */
function pushHistory() {
    window.history.pushState(null, null, location.href);
}

/**
 * 添加popstate监听
 */
function addPopstateListener(backCallBack) {
    if (window.addEventListener) {
        window.addEventListener("popstate", backCallBack, false);
    } else {
        window.attachEvent("popstate", backCallBack);
    }
}

/**
 * 移除popstate监听
 */
export function removeBrowserBackListener(backCallBack) {
    if (window.removeEventListener) {
        window.removeEventListener("popstate", backCallBack, false);
    } else {
        window.detachEvent("popstate", backCallBack);
    }
}

页面逻辑:

onMounted(() => {
  // 给拦截监听事件绑定函数
  handleBrowserGoBack(pageBackHandler)
})

// 用户页面返回相关逻辑
const pageBackHandler = () => {
  // 弹出挽留页
  scopeState.retainDialog = true
}

// 用户点击挽留页关闭按钮
const closeReturn = () => {
     // 先删除拦截监听事件
 removeBrowserBackListener(pageBackHandler)
    if (isWeiXin()) {
      // 兼容微信
      setTimeout(function () {
document.addEventListener("WeixinJSBridgeReady", function () {
          parent.WeixinJSBridge.call('closeWindow')
        }, false)
        parent.WeixinJSBridge.call('closeWindow')
      }, 300)
    } else {
      // 根据路由保留记录的长度一直返回
      for (let i = 0; i <= history.length; i++) {
        history.back()
      }
    }
}
阅读 2.7k
2 个回答

改用history.go(-1);试一下应该可以
这个浏览器的缓存也可能会这样, 手动禁用看一下,
不过你哪里为什么直接返回第一页呢, 可以保存第一页的路由然后直接跳转到第一页, 你的那个写法会比较耗性能用户用起来也可能会有影响

说明 Safari 做得很好,其他浏览器应该效仿。
这就去给 Chrome 和 FF 提 issue 🤔

不过如果在进入页面之后进行两次“真正的”跳转再到达内容页,而不是使用 history 压栈魔法,也就是入口页→专门的挽留页→内容页,应该就可以“拦截”回退操作。 至于用户体验上的问题,都到考虑做挽留这种事情的地步了,口碑自然也是有点酸臭的了,就不必讲究那么多,大不了就做个伪加载页面。
有些彩色网站就是这么做的(捂鼻)。
但是浏览器不是一块木头,任何影响用户体验的 trick ,被用作坏事之后,早晚会被浏览器厂商天降正义。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题