前端必备:JavaScript 精准校验十六进制颜色值
在前端开发中,颜色值的处理是高频场景——无论是表单提交、样式配置还是组件传参,都需要校验用户输入的十六进制颜色值是否合法。本文将带你实现精准的校验逻辑,覆盖 3 位/6 位纯字符、带#前缀等常见场景,同时拆解正则原理,让你不仅能用,还能理解背后的逻辑。

一、校验场景与核心规则
首先明确我们要解决的核心问题:校验字符串是否为 合法的十六进制颜色值 ,这也是前端最常用的颜色校验场景。
十六进制颜色值的核心规范:
- 字符范围:仅包含十六进制字符(0-9、a-f、A-F,大小写均可)
- 长度要求:3 位(如
ccc)或 6 位(如cccccc) - 可选前缀:实际开发中常带
#前缀(如#ccc、#cccccc),需兼容这类场景 - 边界排除:非字符串类型、空值、含空格/特殊字符、位数不符(如 4 位、5 位)均为不合法
二、基础实现:校验无#前缀的纯字符格式
我们先封装基础版校验函数,聚焦 3 位/6 位纯十六进制字符的校验,包含完整的边界判断(排除空字符串、非十六进制字符、位数不符等):
/**
* 校验字符串是否为合法的十六进制颜色值(3 位/6 位,不含#前缀)
* @param {string} colorStr - 待校验的颜色字符串(如 "ccc"、"cccccc")
* @returns {boolean} - 合法返回 true,否则返回 false
*/
function isValidHexColor(colorStr) {
// 先过滤非字符串类型、空字符串、包含空格的情况
if (typeof colorStr !== 'string' || colorStr.trim() === '') {
return false;
}
// 正则说明:
// ^ 匹配字符串开头 | $ 匹配字符串结尾(确保整串匹配,避免部分匹配)
// [0-9a-fA-F] 匹配任意十六进制字符(0-9、小写 a-f、大写 A-F)
// {3} 精确匹配 3 位 | {6} 精确匹配 6 位 | | 表示“或”逻辑
const hexColorReg = /^([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
return hexColorReg.test(colorStr);
}
// 测试用例(直观验证效果)
console.log(isValidHexColor("ccc")); // true(3 位小写合法)
console.log(isValidHexColor("CCCCCC")); // true(6 位大写合法)
console.log(isValidHexColor("123abc")); // true(6 位数字+小写混合)
console.log(isValidHexColor("123")); // true(3 位纯数字)
console.log(isValidHexColor("cccc")); // false(4 位,位数不符)
console.log(isValidHexColor("cccggg")); // false(包含非十六进制字符 g)
console.log(isValidHexColor("")); // false(空字符串)
console.log(isValidHexColor(" ccc")); // false(开头含空格)
console.log(isValidHexColor(123)); // false(入参为数字,非字符串)关键逻辑拆解
- 前置过滤 :先判断入参类型和空值,避免后续正则匹配无效——比如用户传入数字、undefined 或空格字符串,直接返回 false,减少正则执行开销。
- 正则精准匹配 :
^和$是核心,确保整个字符串完全符合规则(比如避免ccc1234这种超长字符串被误判为合法);[0-9a-fA-F]严格限定十六进制字符范围,排除 g、h、%等非法字符。
三、扩展实现:兼容带#前缀的场景
实际开发中,用户输入的颜色值常带 # 前缀(如 #fff 、 #123456 ),我们只需微调正则,即可兼容“带#/不带#”两种情况:
function isValidHexColorWithHash(colorStr) {
if (typeof colorStr !== 'string' || colorStr.trim() === '') {
return false;
}
// 正则新增 #? 表示 # 可选(有或没有都匹配,且仅匹配 1 次)
const hexColorReg = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
return hexColorReg.test(colorStr);
}
// 扩展测试用例
console.log(isValidHexColorWithHash("#ccc")); // true(带#3 位)
console.log(isValidHexColorWithHash("#cccccc")); // true(带#6 位)
console.log(isValidHexColorWithHash("ccc")); // true(无#3 位)
console.log(isValidHexColorWithHash("#123abc")); // true(带#6 位混合字符)
console.log(isValidHexColorWithHash("##ccc")); // false(多个#前缀,非法)扩展说明
#? 是正则中的“可选匹配”语法: ? 表示前面的字符(这里是 # )出现 0 次或 1 次,既兼容带#的场景,又能避免 ##ccc 、 ###123 这类多#前缀的非法值。
四、进阶优化:处理缩写展开场景(可选)
补充一个实用小技巧:前端中 3 位十六进制颜色值(如 #ccc )本质是 6 位的缩写( #cccccc ),如果需要将 3 位值自动展开为 6 位,可在校验通过后添加转换逻辑:
/**
* 校验并标准化十六进制颜色值(3 位转 6 位,带#前缀)
* @param {string} colorStr - 待处理的颜色值
* @returns {string|null} - 标准化颜色值(如#cccccc),非法返回 null
*/
function normalizeHexColor(colorStr) {
if (!isValidHexColorWithHash(colorStr)) {
return null;
}
// 移除#前缀,统一处理
const pureColor = colorStr.replace('#', '');
// 3 位转 6 位:如 ccc → ccccccc
let normalized = pureColor;
if (pureColor.length === 3) {
normalized = pureColor.split('').map(char => char + char).join('');
}
// 补回#前缀,返回标准化格式
return `#${normalized.toLowerCase()}`;
}
// 测试标准化效果
console.log(normalizeHexColor("ccc")); // #cccccc
console.log(normalizeHexColor("#123")); // #112233
console.log(normalizeHexColor("#123456")); // #123456
console.log(normalizeHexColor("invalid")); // null这个扩展函数在表单提交、样式统一化场景中非常实用,能让颜色值格式更规范。
五、总结
- 核心校验规则 :合法十六进制颜色值需满足「字符串类型 + 仅含 0-9/a-f/A-F 字符 + 长度 3/6 位(可选带 1 个#前缀)」,需排除空值、空格、非法字符、位数不符等边界情况。
- 核心正则公式 :无#前缀用
^([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$,带#前缀用^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$。 - 实用扩展 :校验通过后可将 3 位颜色值展开为 6 位,统一格式便于后续样式处理。
掌握这套校验逻辑,能覆盖前端 99%的十六进制颜色值校验场景,无论是表单验证、组件封装还是工具函数开发,都能快速复用。
发布评论
发布评论前请先 登录。
评论列表 0

暂无评论



