做在线设计工具、主题配置面板或者表单配色功能时,取色器几乎是绕不开的组件。传统方案要么依赖Flash时代的遗留代码,要么只能让用户在预设色板里挑颜色,体验并不理想。好在现代浏览器提供了原生的EyeDropper API,开发者可以直接调用系统的吸管工具,让用户从屏幕任意位置吸取颜色。本文介绍这个API的工作机制,并演示如何用jQuery把它封装成一个带实时颜色预览的插件。

EyeDropper API的工作原理与兼容性
EyeDropper API目前已经在Chrome 95及以上版本、Edge 95及以上版本中得到支持,Firefox和Safari暂时没有实现。它的核心能力是唤起一个系统级取色界面,用户移动鼠标时界面会实时显示当前像素的颜色,点击确认后把颜色值以十六进制字符串的形式返回给页面。
使用前需要先做能力检测,判断window.EyeDropper是否存在。这一点很重要,因为在不支持的浏览器里直接调用会抛出ReferenceError,导致整个脚本中断。另外要注意,这个API必须在用户手势触发的上下文中调用,也就是说你不能在页面加载完毕后自动弹出取色器,必须绑定在点击事件里,这是浏览器出于安全考虑做的限制,防止网页偷偷采集用户屏幕内容。
还有一个容易忽略的细节:取色范围是整个屏幕,而不只是当前网页。用户可以切到其他应用窗口去吸取颜色,比如从设计稿、图片编辑软件里直接取色,这正是这个API比自绘色板强大的地方。
用jQuery封装可复用的取色器插件
下面动手写一个jQuery插件。目标是这样:调用$('#btn').eyeDropper(options)之后,点击按钮即可取色,取到的颜色会回填到回调函数和预览面板中。插件内部处理兼容性检测、Promise结果解析和错误捕获,外部使用时只需要关心拿到颜色之后做什么。
先定义插件的默认配置。onPick是取色成功的回调,onFail是失败或取消的回调,preview接受一个选择器字符串,指向页面上的预览元素。整个插件采用jQuery标准的$.fn扩展方式编写,保持和其他jQuery插件一致的使用习惯。
(function ($) {
'use strict';
// 默认配置项
var defaults = {
onPick: null, // 取色成功回调,参数为颜色对象
onFail: null, // 失败或取消回调
preview: null // 预览元素选择器,如 '#colorPreview'
};
$.fn.eyeDropper = function (options) {
options = $.extend({}, defaults, options);
return this.each(function () {
var $btn = $(this);
$btn.on('click.eyeDropper', function () {
// 能力检测,不支持时直接走失败分支
if (!window.EyeDropper) {
if ($.isFunction(options.onFail)) {
options.onFail(new Error('当前浏览器不支持 EyeDropper API'));
}
return;
}
var dropper = new EyeDropper();
dropper.open()
.then(function (result) {
var hex = result.sRGBHex; // 形如 '#aabbcc'
// 更新预览面板
if (options.preview) {
$(options.preview)
.css('background-color', hex)
.text(hex.toUpperCase());
}
if ($.isFunction(options.onPick)) {
options.onPick(hex);
}
})
.catch(function (err) {
// 用户按 Esc 取消时会走到这里
if ($.isFunction(options.onFail)) {
options.onFail(err);
}
});
});
});
};
})(jQuery);这段代码有几个设计要点。第一,事件命名空间用了click.eyeDropper,方便后续通过$btn.off('click.eyeDropper')解绑,避免重复初始化造成事件叠加。第二,open()返回的是Promise,取消取色时会reject,所以catch分支不能省略,否则控制台会出现未捕获的Promise异常。第三,颜色值统一通过result.sRGBHex获取,这是API规范里定义的标准字段。
搭建页面并实现实时颜色预览
插件写好后,页面上需要一个触发按钮和一个预览区域。预览区域除了显示色块本身,还可以同时展示十六进制、RGB两种格式,方便用户直接复制使用。下面是完整的HTML结构和初始化代码。
<div class="picker-demo">
<button id="pickBtn">吸取颜色</button>
<div id="colorPreview" class="color-preview">尚未选取</div>
<div id="colorInfo"></div>
</div>
<script>
// 简单的十六进制转RGB工具函数
function hexToRgb(hex) {
var num = parseInt(hex.slice(1), 16);
return {
r: (num >> 16) & 255,
g: (num >> 8) & 255,
b: num & 255
};
}
$('#pickBtn').eyeDropper({
preview: '#colorPreview',
onPick: function (hex) {
var rgb = hexToRgb(hex);
$('#colorInfo').text(
'HEX: ' + hex.toUpperCase() +
' / RGB: ' + rgb.r + ', ' + rgb.g + ', ' + rgb.b
);
},
onFail: function (err) {
$('#colorInfo').text(err.message || '取色已取消');
}
});
</script>样式方面可以给预览区域设置一个最小宽高和过渡效果,取色完成后色块平滑切换,观感会好很多。用CSS的transition属性给background-color加上0.3秒的过渡即可,不需要写一行JS动画代码。
如果产品要求复制颜色值到剪贴板,可以在onPick回调里追加navigator.clipboard.writeText(hex)。剪贴板API同样要求用户手势上下文,好在回调本身就是由点击触发的,直接调用没有问题。不过要留意思路切换后的焦点问题,个别浏览器在Promise链较深时会拒绝剪贴板写入,稳妥的做法是提示用户手动复制预览面板里的文字。
降级方案与常见坑
面对不支持EyeDropper的浏览器,最实用的降级方案是回退到HTML原生的<input type="color">控件。它虽然不能从屏幕任意位置取色,但至少能让用户手动挑选颜色,功能不至于完全缺失。可以在插件内部做判断:支持EyeDropper走吸管流程,不支持则自动触发隐藏的color控件。
另一个思路是接入第三方取色库,比如基于canvas的自绘色板方案,但这类方案只能取页面内部的颜色,能力上和原生API有本质差距,建议只作为兜底。
最后总结几个实际开发中容易踩的坑。一是不要把new EyeDropper()的实例创建放在页面加载时,某些浏览器会警告,正确做法是在点击回调里按需创建。二是HTTPS是硬性要求,本地用file://协议打开页面时API可能不可用,调试时建议起一个本地HTTP服务。三是如果页面上有多个取色按钮,务必用each遍历并保持事件命名空间独立,否则取色结果可能回填到错误的预览面板。处理好这些细节,这个封装好的jQuery取色器就可以稳定地用在生产项目里了。
EyeDropper APIjQuery取色器网页取色修改时间:2026-09-03 09:34:54