yt-navigate-finish事件触发时如何获取YouTube新页面的正确标题?
问题原因
YouTube 采用客户端渲染实现页面导航,yt-navigate-finish 事件触发时仅保证路由跳转完成、window.location.href 已经更新为新地址,但document.title的更新逻辑在该事件触发后才会执行,因此此时直接读取标题会拿到上一个页面的缓存值。
解决方案
以下是三种不同适配思路,可根据场景选择:
方案1:加短延迟等待标题更新
实现最简单,适合自用轻量脚本,100ms的延迟足以覆盖绝大多数场景的标题更新耗时:
function run() { setTimeout(() => { browser.runtime.sendMessage({ action: "notify", payload: { url: window.location.href, title: document.title, }, }); }, 100); } window.addEventListener("yt-navigate-finish", run, true);
方案2:监听标题变化后再执行逻辑
稳定性最高,完全不受页面渲染速度影响,通过MutationObserver监听title元素变更,更新后立即触发消息发送:
function sendNotify() { browser.runtime.sendMessage({ action: "notify", payload: { url: window.location.href, title: document.title, }, }); } function run() { const titleNode = document.querySelector('title'); // 先判断标题是否已经更新,避免不必要的监听 if (titleNode.textContent !== window.oldTitle) { sendNotify(); window.oldTitle = titleNode.textContent; return; } // 未更新则启动监听 const titleObserver = new MutationObserver(() => { sendNotify(); titleObserver.disconnect(); window.oldTitle = titleNode.textContent; }); titleObserver.observe(titleNode, { childList: true }); } window.oldTitle = document.title; window.addEventListener("yt-navigate-finish", run, true);
方案3:直接读取页面内的视频标题元素
可以拿到不带「- YouTube」后缀的纯净视频标题,且元素渲染时机早于document.title更新:
function run() { // 取页面内渲染的视频标题,兜底用document.title const videoTitle = document.querySelector('h1.ytd-watch-metadata yt-formatted-string')?.textContent || document.title; browser.runtime.sendMessage({ action: "notify", payload: { url: window.location.href, title: videoTitle, }, }); } window.addEventListener("yt-navigate-finish", run, true);
内容的提问来源于stack exchange,提问作者relidon
相关产品推荐
相关产品推荐

