Safari扩展中如何检测History API的pushState状态变更?
Safari 扩展检测 pushState 变更的替代方案
核心解决思路:放弃在 background 层监听导航事件,改为在声明式注入的 content script 中 hook History API 的原生方法,配合 popstate 事件监听实现页面跳转感知,这套方案同时兼容所有主流浏览器,无需单独维护多平台适配分支。
第一步:调整 manifest.json 配置
去掉 webNavigation 权限,改为声明式注入 content script,确保页面初始加载时就注入脚本:
... "content_scripts": [ { "matches": ["https://*.youtube.com/*"], "js": ["/content.js"], "run_at": "document_start" } ], "permissions": ["https://*.youtube.com/*"] ...
run_at 设置为 document_start 是为了确保在页面自身 JS 执行前就完成 History API 的 hook,避免漏监跳转事件。
第二步:在 content.js 中实现跳转监听逻辑
// 先保存原生History方法 const originalPushState = history.pushState const originalReplaceState = history.replaceState // 页面跳转后需要执行的业务逻辑 function runAfterPageChange() { // 此处写你原本要在content.js中执行的核心逻辑 } // 重写pushState方法,拦截主动跳转行为 history.pushState = function(...args) { const result = originalPushState.apply(this, args) runAfterPageChange() return result } // 重写replaceState方法,拦截替换历史记录的跳转行为 history.replaceState = function(...args) { const result = originalReplaceState.apply(this, args) runAfterPageChange() return result } // 监听浏览器前进/后退触发的popstate事件 window.addEventListener('popstate', runAfterPageChange) // 兼容页面首次加载场景,初始化时执行一次逻辑 document.addEventListener('DOMContentLoaded', runAfterPageChange)
注意事项
如果你的业务逻辑依赖特定 DOM 元素加载,可在 runAfterPageChange 中加入简单的元素轮询判断,避免页面还没渲染完找不到目标节点的问题。
内容的提问来源于stack exchange,提问作者user12532589
相关产品推荐
相关产品推荐

