SnapDOM DOM 截图终极指南:4 行代码把网页元素拍成图
【免费下载链接】snapdomHigh-performance engine for capturing, modifying, and converting DOM elements into any format.项目地址: https://gitcode.com/GitHub_Trending/sn/snapdom
SnapDOM 是一个浏览器 DOM 截图引擎,把任意元素转成 SVG、PNG、JPG、WebP 或带图 HTML,字体样式原样保留、零依赖、全程跑在页面里。4 行代码,你就能拿到一张生产级元素截图。
截图痛点有哪些能靠 SnapDOM 解决
它专治"页面就在用户浏览器里,截图却绕道服务器"这件事:
- 管理后台分享卡片:想把图表卡片发给客户,后端截图要部署无头浏览器,太重。
- 在线编辑器出图:用户编辑完点"分享图片",页面在用户浏览器里,捕获也理应发生在本地,无需服务端。
- 给 AI 喂页面状态:把当前界面变成图片或结构化上下文,必须现场捕获,不能等请求来回。
- 弱网现场作业:捕获本身不额外发请求,资源已经在页面上,离线照样出图。
能力地图:捕获流水线里各模块干什么
入口只有一个snapdom(element, options),返回的是一个"捕获态快照",之后任意格式导出都不再重渲染页面:
- src/api/snapdom.js:对外 API 与选项校验,流水线的第一站。
- src/core/capture.js:主流程编排,克隆、样式收集、光栅化与差异复用都收口在这里。
- src/modules/fonts.js:识别页面实际使用的 web 字体并内嵌,防止截图字体漂移。
- src/exporters/:
toPng、toJpg、toWebp、toSvg、toCanvas、toBlob、download等导出方法都在这。 - packages/plugins/:PDF、GIF、视频、打码、时间戳等官方插件,按需安装。
- BENCHMARKS.md:真实场景的实测耗时,选方案时先看它。
快速上手:4 行代码拍一张元素截图
先npm i @zumer/snapdom(无依赖),然后:
import { snapdom } from '@zumer/snapdom' const result = await snapdom(document.querySelector('#card')) const png = await result.toPng() document.body.appendChild(png)三个最常碰的参数:
scale/dpr:控制输出分辨率,默认跟随设备像素比。width/height:钉死输出尺寸,只设一个时自动保持宽高比。exclude:按选择器剔除节点,配excludeMode: 'remove'才连布局一起删。
三种捕获方式怎么选:一步快捷、结果复用、预热
结论:单张偶发出图用一步快捷;同一状态要多种产物用结果复用;固定按钮出图用预热。按下表对号入座:
| 方式 | 适用场景 | 优点 | 局限 | 推荐指数 |
|---|---|---|---|---|
一步快捷snapdom.toPng(el, opts) | 偶发单图 | 代码最少,无中间变量 | 想换格式再导要重新捕获 | ★★★ |
结果复用snapdom(el)后导出 | 同一状态出多种格式 | 捕获一次导出无限次,且不受页面后续变化影响 | 需要自己持有 result 对象 | ★★★★★ |
snapdom.preCapture()预热 | 固定的导出按钮 | 首次点击学会目标,之后 hover 提前备好,点下去零等待 | 只对该按钮生效 | ★★★ |
真实项目里最常用的是结果复用,捕获一次后自由组合产物:
const result = await snapdom(card, { scale: 2 }) const png = await result.toPng() const blob = await result.toBlob({ format: 'webp', quality: 0.75 }) await result.download({ format: 'png', filename: 'card' })调优 3 个点:尺寸、剔除、缓存
出高清图最常调的是width与dpr的组合:width定 CSS 宽度,dpr再乘实际像素,打印级直接给到 2 起步。
const result = await snapdom(card, { width: 480, dpr: 2, backgroundColor: '#ffffff' }) const blob = await result.toBlob({ format: 'png' })清页面:想让工具栏、广告条不出现在截图里,用exclude列选择器。模式二选一,'remove'让节点彻底消失、周围内容补位;默认'hide'保留不可见占位,布局不塌:
const result = await snapdom(card, { exclude: ['.toolbar', '.no-print'], excludeMode: 'remove' })缓存不用你操心:v3 对未变化的捕获自动复用,重复截图是毫秒级的(BENCHMARKS.md 里复杂卡片实测 10 ms)。只有一处要盯紧:sheet.insertRule()这类引擎看不见的 CSSOM 改动,必须显式传invalidate: true,否则拿旧图;把exclude写成函数则会关闭记忆化,轮询页每帧都全量捕获。
它实际能干哪些活:仪表盘 PDF 与像素级回归
下面两个案例都发生在浏览器里,没有后端参与。
第一个是文档导出:装上插件包后,把官方pdf-image插件挂进plugins数组,捕获先渲染成图再排版进 PDF 页。Kong UI Components 就这么做:仪表盘在浏览器端直接出 PDF 给客户下载。图基方案的好处是 PDF 里不依赖字体和字体网络,所见即所得。
第二个是像素级回归:这个项目自己的测试套件就是给 DOM 截图、和基线图逐像素对比(方法可对照 BENCHMARKS.md);官方出品的视觉回归工具 SnapDIFF 同样基于这条捕获管线。大页面建议先调低scale出一版小图再比对,把 CI 时长压住。
避坑清单:上线前对一遍的 6 个误区
坑大多不来自 API 本身,而来自预期和引擎行为对不上:
width和scale都传、指望相乘 → v3 里 width 优先,scale 被忽略,出图分辨率低于预期。- 用
sheet.insertRule()改完 CSSOM 直接截 → 引擎感知不到变化,产出旧图,记得invalidate: true。 - 为拿实时逻辑把
exclude写成函数 → 该次捕获关闭记忆化与增量重建,轮询页每帧全量捕获。 - 以为 SVG 产物哪都能开 → 它用
<foreignObject>内嵌 HTML,部分办公与文档工具里会空白。 - 假设跨域图片自动可用 → 无 CORS 的资源会缺图,需要可读资源或代理。
- 把不可信 HTML 直接喂给
fromString()→<img onerror>这类内联事件会在你的源里执行,先过一遍 DOMPurify 之类的清洗。
到这里,从单元素出图到多格式产物管线都齐了。现在就去把页面上那张卡片的toBlob({ format: 'webp' })跑一遍,一分钟见效果 🚀
【免费下载链接】snapdomHigh-performance engine for capturing, modifying, and converting DOM elements into any format.项目地址: https://gitcode.com/GitHub_Trending/sn/snapdom
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考