EyeDropper API 是 Chrome 113+、Edge 113+、Opera 99+ 原生支持的 JavaScript 构造函数,需用户手势触发且仅限安全上下文,返回屏幕合成后的 RGB 值(无 alpha),不支持 Firefox/Safari,无法被纯前端 polyfill 真实实现。

EyeDropper API 在 Chrome 113+ 中直接可用
现代 Chrome(113 及以上)、Edge(113+)、Opera(99+)已原生支持 EyeDropper API,无需第三方库或模拟实现。它不是 CSS 功能,也不是 HTML 标签,而是一个 JS 构造函数,调用后会触发系统级取色器——用户点哪,就返回哪的 rgb(r, g, b) 或 hex(需自行转换)。
关键限制:必须由**用户手势触发**(如 click、pointerdown),不能自动调用;且仅在安全上下文(https:// 或 localhost)中可用。
const eyeDropper = new EyeDropper();
button.addEventListener('click', async () => {
try {
const result = await eyeDropper.open();
console.log(result.sRGBHex); // "#ff5733"
console.log(result.red, result.green, result.blue); // 255, 87, 51
} catch (err) {
console.error(err.name); // "NotAllowedError" 或 "AbortError"
}
});
不支持 EyeDropper 的浏览器怎么 fallback
Firefox、Safari 目前(截至 2024 年中)仍不支持 EyeDropper。硬上 polyfill 不现实——没有底层像素读取权限,纯前端无法绕过 CORS 和 canvas 像素限制去“吸”网页外的颜色。
可行 fallback 方案只有两个方向:
立即学习“前端免费学习笔记(深入)”;
- 提供手动输入框 + 颜色预览,搭配
<input type="color">(注意:该控件只返回 hex,且在 Safari 中行为不一致,iOS 尤其简陋) - 用 canvas +
getImageData()实现“页面内吸色”:先让用户截图/上传图片,或限定吸色区域为当前页面某块<canvas></canvas>或带crossOrigin的图片——但这不是真正意义的“屏幕吸管”,只是局部采样
别信 npm 上标榜“跨浏览器 EyeDropper”的包,它们要么是 UI 模拟器(点哪显示个色块,但没真读屏幕),要么依赖桌面端 Electron/TAURI 扩展,和纯 HTML/JS 无关。
常见报错:NotAllowedError: Permission denied
这个错误几乎总是因为触发时机不对。即使绑在 click 上,如果逻辑里有异步延迟(比如 setTimeout、await 等待非用户事件),浏览器会认为操作“脱离用户意图”,直接拒掉。
典型翻车写法:
button.addEventListener('click', () => {
setTimeout(() => { // ❌ 延迟导致失去用户手势上下文
eyeDropper.open();
}, 100);
});
正确做法:所有 eyeDropper.open() 必须在同步执行路径中,或至少在用户事件处理函数的直接调用栈里。如果必须异步,可用 Promise.resolve().then(() => eyeDropper.open())(微任务仍算“紧邻”),但更稳妥的是把后续逻辑放进 open() 的 then 或 await 后。
返回值里没有 alpha?怎么处理透明色
EyeDropper 返回的 result 对象目前**不包含 alpha 通道信息**,sRGBHex 是 6 位(如 #ff5733),red/green/blue 是 0–255 整数。它本质上读的是屏幕合成后的 RGB 值,不管原始图层是否有 opacity 或 rgba。
这意味着:如果你吸的是一个 rgba(255, 0, 0, 0.5) 叠在白色背景上的文字,实际拿到的是混合后接近 #ff8080 的值,而非原始 alpha。
需要精确 alpha 的场景(如设计工具),只能放弃 EyeDropper,改用桌面应用方案(Tauri/Electron 调系统 API)或浏览器扩展(需 activeTab + scripting 权限注入内容脚本读 DOM 计算)。纯网页做不到。
真实项目里,多数情况只要 RGB 就够用;真要处理半透,得提前约定好“吸色仅用于 UI 主题色选取”,并明确告知用户:吸的是最终呈现色,不是源定义色。



















