Skip to content

Content Script 注入机制 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构与注入入口
  3. Content Script 生命周期与注入时机
  4. 消息路由表与异步处理模型
  5. 页面工具集合组织结构
  6. Shadow DOM 穿透与跨边界访问
  7. 选区工具栏实现
  8. 关键流程与调用序列图
  9. 依赖关系分析
  10. 性能优化、内存管理与兼容性最佳实践
  11. 故障排查指南
  12. 结论

引言 ​

本文围绕扩展的 Content Script 注入机制展开,重点解释以下内容:

  • Content Script 的生命周期、注入时机与 document_idle 的实际影响。
  • 基于 Map 的消息路由表设计、异步工具通道保持策略和错误传播方式。
  • 页面工具集合的分类:信息提取、交互操作、数据处理与高级能力。
  • Shadow DOM 与 iframe 穿透方案、选择器生成与坐标计算。
  • 选区工具栏的悬浮定位、拖拽、DOM 操作和用户反馈。
  • 注入流程图、工具调用序列图和页面交互示意图。
  • 性能优化、内存管理和 MV3 兼容性注意事项。

本项目为双进程架构:Chrome 扩展端(Manifest V3)与独立本地代理端 Agent 通过 HTTP/WebSocket 通信;本文聚焦扩展端的 Content Script 层,不涉及 Agent 内部执行逻辑。

章节来源

项目结构与注入入口 ​

Content Script 的入口由 Manifest 声明,并在浏览器加载页面时按规则注入。核心文件职责如下:

文件主要职责
manifest.json声明 Content Script 匹配规则、注入脚本、CSS、注入时机和跨帧行为
src/content/index.js消息路由表、快捷键、区域截图选择、全局错误兜底、初始化选区工具栏
src/content/page-tools.js基础页面读取工具:文本、HTML、选区、表格、剪贴板、悬停、高亮
src/content/page-extract.js元数据、链接、表单、图片、Markdown、JSON、iframe 内容、页面搜索
src/content/page-interaction.js可交互元素查询、ref 注册表、快照采集、滚动收集、按 ref 交互
src/content/interaction-tools.js点击、表单填充、滚动、等待元素、键盘输入、文件上传、下拉选择、存储管理
src/content/advanced-tools.js二维码、CSS 注入、性能审计、完成度校验、安全净化
src/content/shadow-dom-utils.jsShadow DOM 与 iframe 深度查询、选择、文本、HTML、选择监听、坐标计算
src/content/selection-toolbar.js选中文本浮动工具栏、结果面板、i18n、拖拽、溢出菜单、Token 展示
graph TB
Manifest["manifest.json<br/>声明 content_scripts"] --> Index["src/content/index.js<br/>消息路由 + 初始化"]
Index --> PageTools["page-tools.js<br/>基础读取工具"]
Index --> PageExtract["page-extract.js<br/>信息提取工具"]
Index --> PageInteraction["page-interaction.js<br/>交互查询 + ref 注册"]
Index --> InteractionTools["interaction-tools.js<br/>点击/表单/键盘/上传"]
Index --> AdvancedTools["advanced-tools.js<br/>二维码/CSS/完成度校验"]
Index --> SelectionToolbar["selection-toolbar.js<br/>选区工具栏"]
PageTools --> ShadowUtils["shadow-dom-utils.js<br/>Shadow DOM / iframe 穿透"]
PageExtract --> ShadowUtils
PageInteraction --> ShadowUtils
InteractionTools --> ShadowUtils
SelectionToolbar --> ShadowUtils

图表来源

章节来源

Content Script 生命周期与注入时机 ​

注入配置 ​

Manifest 中 Content Script 的关键配置如下:

  • matches: <all_urls>,表示对所有网页生效。
  • js: 先注入 libs/qrcode.min.js,再注入 libs/marked.min.js,最后注入 src/content/index.js。
  • css: 注入 styles/styles.css。
  • run_at: document_idle。
  • all_frames: true,允许在所有 frame 中注入。
  • match_about_blank: true,兼容空页面。
  • match_origin_as_fallback: true,同源回退匹配。

这意味着 Content Script 在文档空闲阶段注入,而不是更早的 document-start。该选择有利于:

  • 页面结构基本可用,减少因 DOM 未就绪导致的查询失败。
  • 降低对首屏渲染的阻塞风险。
  • 更适合以“读取页面 + 用户交互”为主的扩展场景。

但这也意味着:

  • 如果需要在极早期拦截网络或修改初始 DOM,应改用 document-start 并谨慎评估性能。
  • 当前实现依赖 document.body、chrome.runtime、window.top 等运行时对象存在。

运行期生命周期 ​

Content Script 启动后执行以下关键步骤:

  1. 导入各模块工具函数。
  2. 注册 i18n 翻译键。
  3. 初始化国际化。
  4. 打印调试日志,记录 URL、是否顶层 frame、是否存在 document.body。
  5. 注册全局快捷键:组合键打开扩展 action、全页截图、区域截图。
  6. 构建消息路由表 HANDLERS 和异步工具集合 ASYNC_HANDLERS。
  7. 定义仅顶层 frame 响应的类型集合 TOP_FRAME_ONLY_TYPES。
  8. 在扩展上下文有效时注册 chrome.runtime.onMessage。
  9. 注册全局错误和未处理 Promise 拒绝过滤器,屏蔽 Extension context invalidated。
  10. 等待 i18n 就绪后初始化选区工具栏。
  11. 提供区域截图选择函数,供消息路由调用。
flowchart TD
Start["Content Script 加载"] --> ManifestCheck["检查 manifest 注入配置"]
ManifestCheck --> I18nInit["初始化 i18n"]
I18nInit --> LogContext["输出页面上下文日志"]
LogContext --> RegisterShortcuts["注册快捷键事件"]
RegisterShortcuts --> BuildHandlers["构建 HANDLERS 路由表"]
BuildHandlers --> DefineAsyncSet["定义 ASYNC_HANDLERS 集合"]
DefineAsyncSet --> DefineTopFrameOnly["定义 TOP_FRAME_ONLY_TYPES 集合"]
DefineTopFrameOnly --> CheckExtensionValid{"扩展上下文有效?"}
CheckExtensionValid --> |是| RegisterMessageListener["注册 onMessage 监听"]
CheckExtensionValid --> |否| SkipListener["跳过消息监听"]
RegisterMessageListener --> GlobalErrorGuard["注册全局错误与未处理拒绝过滤"]
SkipListener --> GlobalErrorGuard
GlobalErrorGuard --> WaitI18nReady["等待 i18n 就绪"]
WaitI18nReady --> InitSelectionToolbar["初始化选区工具栏"]
InitSelectionToolbar --> Ready["Content Script 就绪"]

图表来源

章节来源

消息路由表与异步处理模型 ​

路由表设计 ​

index.js 使用对象字面量作为消息路由表,键为消息类型,值为处理器函数。这种设计具备以下特点:

  • 查找复杂度接近 O(1)。
  • 新增工具只需添加键值对,无需遍历数组。
  • 分类清晰:页面读取、页面交互、表单输入、信息提取、媒体输出、异步工具、区域截图、页面度量。

路由表覆盖的主要类别包括:

  • 页面读取:获取页面文本、完整 HTML、查询交互元素、获取选中内容、子帧快照采集。
  • 页面交互:按 ref/text/selector 交互、填充表单、滚动到目标。
  • 表单输入:键盘输入、文件上传。
  • 信息提取:表格、元数据、链接、表单、图片、页面搜索、iframe 内容、滚动收集。
  • 媒体输出:存储管理、CSS 注入、完成度校验。
  • 异步工具:剪贴板、等待元素、下拉选择、二维码、区域截图。
  • 页面度量:页面宽高指标。

异步处理模型 ​

异步工具分为两类:

  1. 显式标记为异步的工具:COPY_TO_CLIPBOARD、PASTE_FROM_CLIPBOARD、WAIT_ELEMENT、SELECT_DROPDOWN、QRCODE、START_REGION_SELECTION,以及 INTERACT_ELEMENT、SCROLL_TO、KEYBOARD_INPUT 的某些分支。
  2. 返回 Promise 的处理器。

消息监听器统一处理同步和异步返回值:

  • 如果消息类型属于 ASYNC_HANDLERS,或者返回值是 Promise,则保持消息通道开放,并在 Promise resolve 后回复。
  • 否则直接同步回复。
sequenceDiagram
participant Background as "Background / Side Panel"
participant Content as "Content Script index.js"
participant Handler as "HANDLERS 处理器"
participant Tool as "具体工具模块"
Background->>Content : chrome.runtime.sendMessage({ type, payload })
Content->>Content : 判断 TOP_FRAME_ONLY_TYPES
Content->>Content : 查找 HANDLERS[type]
Content->>Handler : 调用处理器
alt 异步工具或返回 Promise
Handler-->>Content : Promise
Content->>Content : Promise.resolve(result).then(sendResponse)
Content-->>Background : sendResponse(result)
else 同步工具
Handler-->>Content : 同步结果
Content-->>Background : sendResponse(result)
end

图表来源

错误传播机制 ​

错误传播遵循统一模式:

  • 工具函数通常返回 { success, data?, error?, message? } 结构。
  • 路由层不吞掉业务错误,而是将工具返回的错误原样传给调用方。
  • 对于扩展上下文失效,Content Script 通过全局 error 和 unhandledrejection 事件过滤,避免控制台刷屏。
  • 部分工具在 try-catch 中捕获异常,并转为结构化错误响应。

需要注意:

  • 异步工具的错误由 Promise reject 或工具内部返回 { success: false, error } 表达。
  • 路由层对 Promise 使用 Promise.resolve(result),因此即使处理器返回 rejected Promise,也会被包装成 resolved Promise,最终通过 sendResponse 传递;若需要区分 reject 与业务错误,应在工具层明确返回结构化错误。

章节来源

页面工具集合组织结构 ​

页面工具按职责拆分为多个模块,便于维护和测试:

分类文件典型功能
基础读取page-tools.js获取页面文本、HTML、选区、表格、剪贴板、悬停、文本高亮
信息提取page-extract.js元数据、链接、表单、图片、Markdown、JSON、iframe、搜索
交互查询page-interaction.js可交互元素查询、ref 注册、快照采集、滚动收集、按 ref 交互
交互操作interaction-tools.js点击、表单填充、滚动、等待元素、键盘输入、文件上传、下拉选择、存储管理
高级能力advanced-tools.js二维码、CSS 注入、性能审计、完成度校验、CSS 安全净化
底层穿透shadow-dom-utils.jsShadow DOM、iframe、选择、文本、HTML、选择监听、坐标计算
用户界面selection-toolbar.js选区工具栏、结果面板、拖拽、溢出菜单、Token 明细

基础读取工具 ​

page-tools.js 提供轻量、稳定的页面读取能力:

  • getPageText:提取标题、URL、正文、词数、可选标题和链接。
  • getFullHtml:提取完整 HTML,支持去除内联样式和长度限制。
  • getSelectedContent:读取用户选区,支持 text/html 两种格式。
  • extractTable:解析表格为 JSON 或 Markdown。
  • copyToClipboard / pasteFromClipboard:剪贴板读写,带降级方案。
  • hoverElement:触发鼠标悬停,并自动检测导航或 DOM 变化。
  • highlightText:移除旧高亮、插入样式、遍历文本节点包裹高亮 span。

信息提取工具 ​

page-extract.js 负责结构化信息抽取:

  • extractMetadata:meta、Open Graph、Twitter Card、JSON-LD、Microdata。
  • extractLinks:链接列表,支持内外链过滤和图片链接。
  • extractForms:表单字段序列化,包含 input、textarea、select。
  • extractImages:图片列表,支持尺寸过滤、背景图、下载。
  • pageToMarkdown:HTML 转 Markdown。
  • pageToJson:结构化表格、列表、JSON-LD、文章、Microdata。
  • getIframeContent:同源 iframe 内容读取。
  • searchInPage:页面内搜索,支持 plain/regex、大小写、上下文、高亮。

交互查询与操作 ​

page-interaction.js 和 interaction-tools.js 共同构成页面自动化能力:

  • queryInteractiveElements:生成可交互元素树快照。
  • collectSnapshotOps:采集 overlay tree、body tree、frame info。
  • interactByRef:按 ref 点击、悬停、输入。
  • clickElement:点击元素并自动等待稳定。
  • fillForm:多字段表单填充,支持原生控件、contenteditable、checkbox/radio/select。
  • scrollToPosition:滚动到顶部、底部、坐标或元素。
  • waitForElement:等待元素出现、消失、可见、隐藏。
  • keyboardInput:模拟按键和文本输入。
  • fileUpload:通过 DataTransfer 设置文件。
  • clickByText:按文本查找并点击或悬停。
  • selectDropdown:原生 select 或自定义下拉选择。
  • manageStorage:localStorage/sessionStorage 的 get/set/remove/clear。

章节来源

Shadow DOM 穿透与跨边界访问 ​

设计目标 ​

现代前端大量使用 Shadow DOM 和 iframe,普通 querySelector 无法穿透。shadow-dom-utils.js 提供统一穿透能力:

  • 递归遍历 shadowRoot。
  • 尝试访问同源 iframe 的 document。
  • 跨域 iframe 被安全跳过。
  • 提供选择器、全选、选区、文本、HTML、路径选择器、视口坐标、选择监听等工具。

核心 API ​

API用途关键点
deepQuerySelector穿透 Shadow DOM 和 iframe 查询单个元素优先深层匹配,跨域跳过
deepQuerySelectorAll穿透查询所有匹配元素使用 Set 去重
deepGetSelection获取 Shadow DOM 中的选区返回 text 和 range
deepGetText合并页面文本防止循环引用,trim 多余换行
deepGetHtml合并页面 HTML标注 shadow-root 和 iframe 片段
getDeepSelector生成包含 Shadow DOM 路径的选择器记录 shadowHost 层级
findShadowRoot查找元素所属 ShadowRoot向上回溯 root
getElementViewportPosition元素视口坐标累加 iframe 偏移
getRangeViewportPosition选区范围视口坐标处理 iframe 嵌套
attachSelectionListeners在所有 Shadow DOM 上附加 selectionchange返回监听器集合
removeSelectionListeners清理监听器防止内存泄漏
hasShadowDom / hasIframe能力检测安全 try-catch
flowchart TD
Input["选择器或 Range"] --> Traverse["遍历 DOM 树"]
Traverse --> ShadowCheck{"存在 shadowRoot?"}
ShadowCheck --> |是| RecurseShadow["递归进入 shadowRoot"]
ShadowCheck --> |否| IframeCheck{"存在 iframe/frame?"}
IframeCheck --> |是| TryAccess["尝试访问 contentDocument"]
TryAccess --> AccessOk{"同源可访问?"}
AccessOk --> |是| RecurseIframe["递归进入 iframe document"]
AccessOk --> |否| SkipIframe["跳过跨域 iframe"]
RecurseShadow --> Query["执行 querySelector/querySelectorAll"]
RecurseIframe --> Query
SkipIframe --> Query
Query --> Result["返回元素或结果集"]

图表来源

与页面工具的协作 ​

  • page-tools.js 使用 deepGetText、deepGetHtml、deepQuerySelector、deepQuerySelectorAll 读取 Shadow DOM 内容。
  • page-extract.js 同样依赖这些工具进行元数据和结构化数据提取。
  • page-interaction.js 使用 deepQuerySelector 和 deepQuerySelectorAll 定位交互元素。
  • interaction-tools.js 使用 deepQuerySelector 定位点击目标、表单控件和上传控件。
  • selection-toolbar.js 使用 deepGetSelection、getRangeViewportPosition、attachSelectionListeners 实现跨边界选区识别和工具栏定位。

章节来源

选区工具栏实现 ​

选区工具栏是用户与 AI 能力之间的直接交互入口,核心行为包括:

  • 检测页面选区,包括 Shadow DOM 中的选区。
  • 在选区附近显示浮动工具栏。
  • 支持内置工具:AI 搜索、解释、翻译、总结、复制。
  • 支持更多工具溢出菜单、设置、临时禁用、站点禁用。
  • 支持“问问 AI”输入框模式。
  • 支持结果面板:流式渲染、复制、重新生成、推荐追问、Token 消耗明细。
  • 支持拖拽移动、锁定面板、关闭面板。
  • 支持 frameset 页面和 iframe 场景。

工具栏状态与变量 ​

工具栏维护多种状态:

  • 工具栏可见性、询问模式、结果面板可见性。
  • 上次操作类型、自定义提示词、保存的选中文本。
  • 工具栏工具配置缓存、图标精简模式。
  • 流式内容、渲染节流令牌、Token 使用数据。
  • Shadow DOM 选择监听器集合、顶层 frame 判定。
  • frameset 页面宿主判定、拖拽状态、溢出下拉菜单。

悬浮定位与 DOM 操作 ​

工具栏定位依赖:

  • getRangeViewportPosition 计算选区在视口中的位置。
  • appendToDoc 兼容 document.body 不存在的情况,降级到 document.documentElement。
  • 拖拽通过全局 mousemove 和 mouseup 更新 left、top,并限制在视口范围内。
  • 结果面板和工具栏分别挂载到文档,并通过类名控制显示隐藏。

用户交互反馈 ​

  • 按钮支持 Enter/Space 触发。
  • 溢出菜单支持点击、键盘操作。
  • “问问 AI”输入框支持 focus、blur、Enter、Escape。
  • 结果面板支持复制富文本、复制 Markdown、重新生成、发送追问。
  • Token 标签点击弹出消耗明细。
  • 工具名称通过 i18n 动态获取,避免硬编码文案。
sequenceDiagram
participant User as "用户"
participant Toolbar as "selection-toolbar.js"
participant ShadowUtils as "shadow-dom-utils.js"
participant DOM as "页面 DOM"
User->>DOM : 选中文本
DOM-->>Toolbar : selectionchange 事件
Toolbar->>ShadowUtils : deepGetSelection()
ShadowUtils-->>Toolbar : { text, range }
Toolbar->>DOM : 创建工具栏 DOM
Toolbar->>DOM : 计算选区视口位置
Toolbar->>DOM : 显示工具栏
User->>Toolbar : 点击工具按钮
Toolbar->>Toolbar : handleAction()
Toolbar->>DOM : 显示结果面板或发送侧边栏

图表来源

章节来源

关键流程与调用序列图 ​

消息路由调用序列 ​

当 background 或 side panel 调用 Content Script 工具时,典型调用链如下:

sequenceDiagram
participant Caller as "调用方"
participant Runtime as "chrome.runtime"
participant Index as "index.js"
participant Router as "HANDLERS"
participant Module as "具体工具模块"
Caller->>Runtime : sendMessage({ type, ... })
Runtime->>Index : onMessage(message, sender, sendResponse)
Index->>Index : 检查 TOP_FRAME_ONLY_TYPES
Index->>Router : 查找 handler
Router->>Module : 调用工具函数
Module-->>Router : 返回结果或 Promise
Router-->>Index : 结果
Index->>Runtime : sendResponse(result)
Runtime-->>Caller : 收到响应

图表来源

按 ref 交互序列 ​

interactByRef 展示了 ref 解析、元素定位、动作执行和自动等待的完整流程:

sequenceDiagram
participant Caller as "调用方"
participant Index as "index.js"
participant Interaction as "page-interaction.js"
participant Registry as "elementRegistry"
participant Utils as "page-utils.js"
Caller->>Index : INTERACT_ELEMENT(ref=...)
Index->>Interaction : interactByRef(ref, action, options)
Interaction->>Registry : resolveByRef(ref)
alt ref 有效且元素仍连接
Registry-->>Interaction : { entry, element }
else ref 无效或元素断开
Registry-->>Interaction : { error, suggestions }
Interaction-->>Caller : 返回错误与建议
return
end
Interaction->>Utils : 执行 click/hover/type
Utils-->>Interaction : autoWaitAfterAction(...)
Interaction-->>Caller : 返回成功结果与等待信息

图表来源

页面交互示意图 ​

选区工具栏与页面交互的关系如下:

graph TB
Selection["用户选区"] --> Toolbar["选区工具栏"]
Toolbar --> Actions["工具动作:AI 搜索/解释/翻译/总结/复制"]
Actions --> SidePanel["发送到侧边栏或本地代理"]
Toolbar --> ResultPanel["结果面板:流式回答/追问/Token 明细"]
Toolbar --> DOM["DOM 操作:拖拽/显示/隐藏/复制"]
Selection --> ShadowUtils["Shadow DOM 选区穿透"]
ShadowUtils --> Toolbar

图表来源

依赖关系分析 ​

Content Script 模块之间存在清晰的单向依赖:

  • index.js 聚合所有工具模块,作为消息路由入口。
  • page-tools.js 依赖 shadow-dom-utils.js 和 page-utils.js。
  • page-extract.js 依赖 shadow-dom-utils.js 和 page-utils.js。
  • page-interaction.js 依赖 shadow-dom-utils.js、page-utils.js 和共享快照渲染器。
  • interaction-tools.js 依赖 shadow-dom-utils.js、page-utils.js 和 page-interaction.js。
  • advanced-tools.js 依赖 shadow-dom-utils.js。
  • selection-toolbar.js 依赖 shadow-dom-utils.js、selection-toolbar-styles.js、i18n 和 logger。
graph LR
Index["index.js"] --> PageTools["page-tools.js"]
Index --> PageExtract["page-extract.js"]
Index --> PageInteraction["page-interaction.js"]
Index --> InteractionTools["interaction-tools.js"]
Index --> AdvancedTools["advanced-tools.js"]
Index --> SelectionToolbar["selection-toolbar.js"]
PageTools --> ShadowUtils["shadow-dom-utils.js"]
PageExtract --> ShadowUtils
PageInteraction --> ShadowUtils
InteractionTools --> ShadowUtils
InteractionTools --> PageInteraction
AdvancedTools --> ShadowUtils
SelectionToolbar --> ShadowUtils

图表来源

章节来源

性能优化、内存管理与兼容性最佳实践 ​

注入时机选择 ​

当前使用 document_idle,适合大多数读取和交互场景。如果需要更早介入,可考虑 document-start,但需注意:

  • DOM 可能尚未就绪。
  • 大量 DOM 操作可能阻塞首屏。
  • 需要更严格的错误处理和降级逻辑。

Map 与 Set 的使用 ​

  • HANDLERS 使用对象字面量作为路由表,查找接近 O(1)。
  • ASYNC_HANDLERS 和 TOP_FRAME_ONLY_TYPES 使用 Set,成员判断 O(1)。
  • elementRegistry 使用 Map,ref 到元素映射高效。
  • elementRefMap 使用 WeakMap,避免阻止元素 GC,同时复用 ref 编号。

异步工具通道保持 ​

异步工具通过 return true 保持消息通道开放,避免 Chrome 提前关闭响应。这要求:

  • 异步工具必须返回 Promise。
  • 路由层统一用 Promise.resolve(result).then(sendResponse) 处理。
  • 工具内部错误应返回结构化 { success: false, error },而非抛出未捕获异常。

内存管理 ​

  • Shadow DOM 选择监听器通过 Set 管理,并提供 removeSelectionListeners 清理。
  • 工具栏工具配置缓存避免重复读取 storage。
  • 高亮样式通过固定 id 替换,避免累积 style 节点。
  • 区域截图遮罩层在完成后主动移除 DOM 节点。

兼容性处理 ​

  • 跨域 iframe 访问被 try-catch 保护,失败时跳过。
  • chrome.runtime 调用被 try-catch 包裹,扩展上下文失效时静默忽略。
  • 全局 error 和 unhandledrejection 过滤 Extension context invalidated。
  • CSS 注入前进行安全净化,剔除危险构造。
  • QRCode 库未加载时使用 Canvas 降级方案。

章节来源

故障排查指南 ​

常见问题 ​

问题可能原因排查建议
消息无响应非顶层 frame 被 TOP_FRAME_ONLY_TYPES 过滤检查消息类型和 _frameRouted 标志
ref 无效元素已断开或页面刷新重新调用 query_elements,查看 suggestions
Shadow DOM 元素找不到选择器未穿透 Shadow DOM使用 deepQuerySelector
工具栏不显示扩展上下文失效或 i18n 未就绪检查全局错误过滤和 isExtensionValid
异步工具卡住未返回 Promise 或未保持通道检查 ASYNC_HANDLERS 和处理器返回值
CSS 注入无效被安全净化剔除检查 sanitizeInjectedCss 白名单
iframe 内容缺失跨域限制确认同源或使用 orchestrator 定向路由

调试技巧 ​

  • 查看 Content Script 控制台日志,确认 URL、顶层 frame、document.body 状态。
  • 使用 GET_PAGE_METRICS 获取页面宽高,验证布局。
  • 使用 QUERY_ELEMENTS 查看可交互元素树快照。
  • 使用 EVALUATE_DONE_CRITERIA 验证完成度条件。
  • 检查 selection-toolbar.js 中的 isTopFrame、toolbarTools、resultRawContent 等状态变量。

章节来源

结论 ​

本项目 Content Script 注入机制以 document_idle 为默认注入点,通过集中式消息路由表统一管理页面读取、交互、提取、高级能力和用户界面。其核心优势包括:

  • 清晰的模块划分和依赖关系。
  • 高效的 Map/Set 路由与异步处理模型。
  • 完善的 Shadow DOM 与 iframe 穿透能力。
  • 健壮的错误处理和扩展上下文失效防护。
  • 可扩展的选区工具栏和结果面板。

在实际使用中,应根据页面特性选择合适的注入时机,合理使用 ref 机制避免脆弱选择器,并注意异步工具通道的正确保持。对于复杂页面,优先使用 query_elements 和 collectSnapshotOps 提供的结构化快照,再结合 interactByRef 进行稳定交互。