You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在页面跳转前捕获history.back事件并校验IsDirty标识状态?

实现方案说明

这个需求实现成本很低,核心是调用浏览器或前端路由提供的跳转前钩子,在钩子回调中读取IsDirty标识即可,不需要额外做复杂的事件拦截。

通用场景适配方案

1. 多页应用/跨页面跳转场景

直接监听浏览器beforeunload事件,该事件会在页面卸载、跳转动作正式执行前触发,完全满足前置查询的要求:

window.addEventListener('beforeunload', (event) => {
  // 跳转前读取IsDirty状态
  const isDirty = /* 替换为你实际的IsDirty取值逻辑 */ false
  if (isDirty) {
    // 可在此处添加自定义逻辑,比如二次确认、数据暂存等
    event.preventDefault()
    // 兼容部分浏览器的拦截规则,需要显式设置returnValue
    event.returnValue = '你有未保存的修改,确定要离开当前页面吗?'
    return event.returnValue
  }
})

2. 单页应用(SPA)内部路由跳转场景

单页应用的内部路由跳转不会触发beforeunload事件,需要用对应框架路由提供的前置守卫钩子实现:

Vue + Vue Router 示例

直接使用组件内置的路由离开钩子:

import { onBeforeRouteLeave } from 'vue-router'

// 在页面组件内声明
onBeforeRouteLeave((to, from, next) => {
  const isDirty = /* 替换为你实际的IsDirty取值逻辑 */ false
  if (isDirty) {
    // 执行你的自定义逻辑,比如弹出确认框
    const allowLeave = confirm('存在未保存的修改,是否确认离开?')
    next(allowLeave) // 传入true允许跳转,false阻止跳转
    return
  }
  next()
})

React + React Router 示例

使用官方提供的拦截钩子:

import { useBlocker, useBeforeUnload } from 'react-router-dom'

function EditPage() {
  const isDirty = /* 替换为你实际的IsDirty取值逻辑 */ false
  // 拦截单页内部路由跳转
  const blocker = useBlocker(() => isDirty)
  // 兼容跨页面跳转的拦截
  useBeforeUnload((event) => {
    if (isDirty) {
      event.preventDefault()
      event.returnValue = '存在未保存的修改,是否确认离开?'
    }
  })

  // 自定义拦截后的弹窗逻辑,用户确认后调用blocker.proceed()即可放行跳转
  if (blocker.state === 'blocked') {
    // 此处放置你的弹窗代码
  }
}

注意事项

  • 不要使用popstate事件做跳转拦截,该事件触发时跳转动作已经进入执行队列,无法阻止,不满足前置查询的要求
  • 新版Chrome、Safari等浏览器会屏蔽beforeunload事件的自定义提示文案,只会显示浏览器默认的提示文本,不需要额外做文案适配
  • 如果是监听页面内自定义的返回按钮,直接给按钮的点击事件加前置判断即可,在跳转代码执行前先读取IsDirty做逻辑处理

内容的提问来源于stack exchange,提问作者F L O W I I I

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:24:03