如何在Chrome扩展中给网页原生函数注入回调?
可行方案:劫持原生函数+消息通信实现触发逻辑
完全可以实现,核心思路是劫持页面原生的UpdatePageComplete函数,在它执行时通过消息通知你的扩展内容脚本,进而执行DOM处理逻辑。以下是具体步骤:
1. 注入脚本到页面全局上下文
扩展的内容脚本和页面的全局JS上下文是隔离的,无法直接修改页面的全局函数,所以需要先把劫持函数的代码注入到页面环境中:
// 内容脚本(比如content.js)中的代码 const injectScript = document.createElement('script'); injectScript.textContent = ` // 保存原生函数的引用,避免覆盖后丢失原有逻辑 const originalUpdate = window.UpdatePageComplete; // 重写原生函数 window.UpdatePageComplete = function() { // 先执行页面原本的逻辑 if (originalUpdate) { originalUpdate.apply(this, arguments); } // 向内容脚本发送事件通知 window.postMessage({ type: 'PAGE_UPDATED' }, '*'); }; `; document.head.appendChild(injectScript); injectScript.remove(); // 注入后移除标签,不污染页面DOM
2. 内容脚本监听消息并执行处理逻辑
在内容脚本中监听页面发送的消息,收到通知后执行你的DOM操作:
// 内容脚本中的代码 window.addEventListener('message', (event) => { // 验证消息来源和类型,避免接收无关消息 if (event.source !== window || event.data.type !== 'PAGE_UPDATED') { return; } // 执行你的DOM处理逻辑 processNewContent(); }); // 示例:处理新内容的函数 function processNewContent() { // 给手机号添加tel链接 document.querySelectorAll('.phone').forEach(el => { const num = el.textContent.trim(); if (!el.querySelector('a[href^="tel:"]')) { const link = document.createElement('a'); link.href = `tel:${num}`; link.textContent = num; el.replaceChildren(link); } }); // 给特定内容元素添加背景色 document.querySelectorAll('.special-item').forEach(el => { el.style.backgroundColor = '#f5f5dc'; }); }
3. 配置扩展权限确保生效
在manifest.json中指定目标域名的匹配规则,确保内容脚本只在目标站点运行:
{ "manifest_version": 3, "name": "你的扩展名称", "version": "1.0", "content_scripts": [ { "matches": ["https://你的目标域名.com/*"], "js": ["content.js"], "run_at": "document_idle" } ] }
额外注意事项
- 如果
UpdatePageComplete函数可能在页面加载早期就被调用,可以把run_at改成document_start,并调整注入脚本的逻辑,确保函数存在后再劫持:injectScript.textContent = ` function hijackUpdate() { const originalUpdate = window.UpdatePageComplete; window.UpdatePageComplete = function() { originalUpdate?.apply(this, arguments); window.postMessage({ type: 'PAGE_UPDATED' }, '*'); }; } // 函数已存在则直接劫持,否则等页面加载完成后再处理 if (window.UpdatePageComplete) { hijackUpdate(); } else { window.addEventListener('load', hijackUpdate); } `;
内容的提问来源于stack exchange,提问作者Bing
相关产品推荐
相关产品推荐

