Firefox扩展开发:如何可靠判断用户是否在观看YouTube视频?
问题分析
你的问题根源在于YouTube是单页应用(SPA):从主页导航到视频页时不会触发整页刷新,因此tabs.onUpdated事件仅在页面手动刷新时才会触发,content script也不会重新加载,导致background的消息无法被接收。
可靠解决方案
直接在content script内处理页面路由变化和元素监听,无需依赖background脚本的消息推送,以下是两种可行方案:
方案1:监听SPA路由变化
通过监听浏览器历史记录的变化,捕获YouTube的页面跳转行为:
修改watchingVideo.js:
// 核心逻辑:检测是否在视频页并执行注入 function handleVideoPage() { if (window.location.pathname === '/watch' && window.location.search) { alert('当前处于YouTube视频页面'); // 示例:找到点赞按钮容器并注入自定义元素 const likeContainer = document.querySelector('#top-level-buttons-computed'); if (likeContainer) { // 避免重复注入 if (document.getElementById('my-custom-btn')) return; const customBtn = document.createElement('button'); customBtn.id = 'my-custom-btn'; customBtn.textContent = '我的笔记'; customBtn.style.marginLeft = '10px'; customBtn.style.padding = '6px 12px'; likeContainer.appendChild(customBtn); // 绑定自定义按钮事件 customBtn.addEventListener('click', () => { console.log('触发笔记功能'); }); } } } // 初始加载时检查页面状态 handleVideoPage(); // 监听浏览器前进/后退事件 window.addEventListener('popstate', handleVideoPage); // 重写pushState/replaceState,捕获手动跳转行为 const originalPushState = history.pushState; history.pushState = function(...args) { originalPushState.apply(this, args); handleVideoPage(); }; const originalReplaceState = history.replaceState; history.replaceState = function(...args) { originalReplaceState.apply(this, args); handleVideoPage(); };
方案2:用MutationObserver监听目标元素
直接监听点赞按钮所在的DOM容器,当元素出现时立即执行注入,更精准:
修改watchingVideo.js:
function injectToLikeArea() { const likeContainer = document.querySelector('#top-level-buttons-computed'); if (likeContainer) { // 防止重复注入 if (document.getElementById('my-custom-btn')) return; const customBtn = document.createElement('button'); customBtn.id = 'my-custom-btn'; customBtn.textContent = '添加笔记'; customBtn.style.backgroundColor = '#282828'; customBtn.style.color = 'white'; customBtn.style.border = 'none'; customBtn.style.borderRadius = '20px'; customBtn.style.padding = '8px 16px'; customBtn.style.marginLeft = '12px'; likeContainer.appendChild(customBtn); // 自定义按钮逻辑 customBtn.addEventListener('click', () => { alert('打开笔记面板'); }); } } // 初始检查 injectToLikeArea(); // 监听DOM变化,等待目标容器出现 const observer = new MutationObserver(() => { injectToLikeArea(); }); observer.observe(document.body, { childList: true, subtree: true });
优化manifest.json
调整匹配规则和脚本运行时机,确保覆盖所有YouTube页面:
{ "manifest_version": 2, "name": "YouTube笔记工具", "version": "1.0.0", "description": "YouTube视频笔记工具", "icons": { "48": "icons/border-48.png" }, "content_scripts": [ { "matches": ["*://*.youtube.com/*"], "js": ["watchingVideo.js"], "run_at": "document_idle" } ], "web_accessible_resources":[ "icons/my_icon.svg" ] }
关键改进点
- 移除了不必要的background脚本逻辑,content script自主处理所有场景
- 覆盖了直接打开视频页和从主页导航到视频页两种路径
- 通过防重复注入逻辑避免DOM元素冗余
内容的提问来源于stack exchange,提问作者Diehardwalnut
相关产品推荐
相关产品推荐

