EyeDropper API 不支持 signal 选项,Esc 取消会自动 reject Promise 并抛出 AbortError;需用 try/catch 捕获并重置 UI 状态;兼容性须先检测构造函数存在性,兜底用 input[type=color]。

EyeDropper.signal 不是标准 API,直接使用会报错
目前(Chrome 119+)的 EyeDropper API **根本不支持 signal 选项**。你如果在调用 open() 时传入 { signal: abortController.signal },浏览器会直接抛出 TypeError: Failed to execute 'open' on 'EyeDropper': option 'signal' is not supported。这不是兼容性问题,而是规范里压根没定义这个字段 —— 所以别在参数里硬加 signal,它不会生效,也不会让 Esc 生效。
Esc 取消取色靠的是系统级交互,无需 JS 主动监听
Chrome 和 Edge 中,用户点击取色器后,只要按 Esc 键,open() 返回的 Promise 就会自动 reject,并抛出 DOMException,name 为 "AbortError"(注意不是 "AbortError" 的所有情况都代表用户按了 Esc,但当前场景下基本等价)。这是浏览器原生行为,你不需要、也不应该手动绑定 keydown 监听 Esc。
实操建议:
- 始终用
try/catch包裹eyeDropper.open()调用 - 在
catch中检查error.name === "AbortError",即可确认是用户主动取消 - 不要尝试在
open()前禁用 Esc 或覆盖默认行为 —— 无效且违反可访问性
const eyeDropper = new EyeDropper();
try {
const result = await eyeDropper.open();
console.log("选中颜色:", result.sRGBHex);
} catch (error) {
if (error.name === "AbortError") {
console.log("用户按 Esc 取消了取色");
} else {
console.error("取色失败:", error);
}
}
想实现“取消后自动恢复 UI”,得靠 Promise 拒绝后的状态清理
常见错误是只处理成功路径,忽略拒绝后按钮仍处于 loading 状态、遮罩未移除等问题。因为 open() 拒绝不等于“没发生”,它意味着用户已进入取色流程又退出,UI 应该响应这个中间态。
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
典型场景和要点:
- 点击按钮触发取色前,应设为
disabled并添加 loading 提示 -
catch分支里必须重置按钮状态、移除 loading、还原焦点(尤其当按钮被blur过) - 避免在
catch里直接return后什么都不做 —— 用户会觉得“点了没反应” - 不要用
setTimeout延迟重置状态:Promise 拒绝是同步感知的,延迟反而造成 UI 卡顿感
兼容性兜底必须单独判断 EyeDropper 构造函数是否存在
EyeDropper 是实验性 API,Safari 和 Firefox 完全不支持,部分旧版 Chrome 也不支持。不能只靠 try/catch 来检测,因为构造失败是同步报错,open() 根本不会执行。
正确判断方式:
- 先检查
typeof EyeDropper !== "undefined" - 再检查
new EyeDropper()是否能实例化(某些早期版本存在构造函数但不可用) - 兜底方案建议用
<input type="color">,而非自研色盘 —— 它同样响应 Esc 取消,且零依赖
真正容易被忽略的是:即使用户按了 Esc,你也得确保后续还能再次调用 open() —— 某些错误的重试逻辑会在 reject 后销毁 EyeDropper 实例,导致二次调用失败。


















