原文链接:docs.plasmo.com/framework/c…
本文为官网翻译,因感觉AI翻译晦涩难懂,在学习过程中进行翻译总结。
Plasmo 的 CSUI(Content Script UI)定义了一套生命周期体系,用于在内容脚本中挂载和卸载 React、Vue 或 Svelte 组件。尽管每个 UI 库/框架挂载 API都有稍微的不同,但顶层生命周期在很大程度上是相同的。
- 获取锚点
Anchor。 - 创建或定位一个
Root Container。 - 将组件渲染到
Root Container上。
术语
| 术语 | |
|---|---|
| Anchor | 告诉 CSUI 如何以及在哪里挂载你的组件。 |
| Anchor-getter | 告诉 CSUI 如何找到Anchor |
| Overlay | 将组件挂载到顶层覆盖型元素(z-index最大)上。 |
| Inline | 将组件挂载到网页的 DOM 中,放置在目标元素旁边。 |
| Root Container | CSUI创建的用于隔离你的组件的 ShadowDOM 元素。 |
Anchor
Plasmo CSUI的Anchor由以下类型定义:
export type PlasmoCSUIAnchor = {
type: "overlay" | "inline"
element: Element
}
默认情况下,CSUI 生命周期使用document.body元素创建一个覆盖型锚点:
{
type: "overlay",
element: document.body
}
如果定义并导出了任何anchor-getter函数,CSUI 生命周期将使用返回的元素和对应的Anchor类型。由于anchor-getter函数可以是异步的,因此你也可以控制 Plasmo 挂载你的组件的时机。例如,你可以等待特定元素出现在页面上,然后再挂载你的组件。
anchor通过anchor 属性传递给 CSUI。您可以像这样访问它:
import type { PlasmoCSUIProps } from "plasmo"
const AnchorTypePrinter: FC<PlasmoCSUIProps> = ({ anchor }) => {
return <span>{anchor.type}</span>
}
export default AnchorTypePrinter
Overlay
覆盖型的anchor会生成CSUI覆盖型容器,每份 CSUI 的覆盖型容器会批量挂载到单个Root Container元素上。覆盖型容器相对于每个anchor元素进行绝对定位,并具有最大的z-index。然后,你导出的CSUI Component会挂载到每个覆盖型容器上。
如果要指定单个覆盖型锚点,需要导出一个getOverlayAnchor函数:
import type { PlasmoGetOverlayAnchor } from "plasmo"
export const getOverlayAnchor: PlasmoGetOverlayAnchor = async () =>
document.querySelector("#pricing")
如果要指定覆盖型锚点列表,需要导出一个getOverlayAnchorList函数:
import type { PlasmoGetOverlayAnchorList } from "plasmo"
export const getOverlayAnchorList: PlasmoGetOverlayAnchorList = async () =>
document.querySelectorAll("a")
⚠️
getOverlayAnchorList目前没有涵盖动态情况。例如,如果在初始渲染后向网页添加新的锚点,CSUI lifecycle 将无法检测到它。欢迎提交 PR 以改进此功能!
更新位置
默认的覆盖型容器监听窗口滚动事件以使其自身与锚点元素对齐。你可以通过导出一个watchOverlayAnchor函数来自定义覆盖型容器更新其绝对定位的方式。下面的例子每隔 8472 毫秒刷新一次位置。
import type { PlasmoWatchOverlayAnchor } from "plasmo"
export const watchOverlayAnchor: PlasmoWatchOverlayAnchor = (
updatePosition
) => {
const interval = setInterval(() => {
updatePosition()
}, 8472)
// Clear the interval when unmounted
return () => {
clearInterval(interval)
}
}
点击with-content-scripts-ui/contents/plasmo-overlay-watch.tsx以获取示例。
Inline
内联型锚点将CSUI Component直接嵌入到网页中,每个锚点都会在其目标元素旁边派生出一个Root Container。在每个Root Container中,会创建一个Inline Container,然后该内联容器用于挂载导出的CSUI Component。
指定单个内联型锚点,需要导出一个getInlineAnchor函数:
import type { PlasmoGetInlineAnchor } from "plasmo"
export const getInlineAnchor: PlasmoGetInlineAnchor = async () =>
document.querySelector("#pricing")
如果需要在指定单个内联型锚点时同时指定位置,可以这样做:
import type { PlasmoGetInlineAnchor } from "plasmo"
export const getInlineAnchor: PlasmoGetInlineAnchor = async () => ({
element: document.querySelector("#pricing"),
insertPosition: "afterend"
})
如果要指定内联型锚点列表,可以导出一个getInlineAnchorList函数:
import type { PlasmoGetInlineAnchorList } from "plasmo"
export const getInlineAnchorList: PlasmoGetInlineAnchorList = async () =>
document.querySelectorAll("a")
如果要指定具有插入位置的内联锚点列表:
import type { PlasmoGetInlineAnchorList } from "plasmo"
export const getInlineAnchorList: PlasmoGetInlineAnchorList = async () => {
const anchors = document.querySelectorAll("a")
return Array.from(anchors).map((element) => ({
element,
insertPosition: "afterend"
}))
}
点击with-content-scripts-ui/contents/plasmo-inline.tsx以获取示例。
Root Container
Root Container是挂载CSUI Component的位置,内置的Root Container是一个带有plasmo-csui自定义标签的 ShadowDOM 元素。这使得你可以对Root Container及其导出的组件进行样式设置,而不会受到当前宿主网页样式的影响。
自定义 DOM 挂载
Root Container创建一个shadowHost(影子宿主),该影子宿主被注入到网页的 DOM 树中。默认情况下,Plasmo 在内联型锚点的元素之后以及覆盖型锚点的document.body之前注入shadowHost。要自定义此行为,请导出一个mountShadowHost函数。