生成可控范围16进制随机颜色
<style>.artBox { font: normal 18px/1.2 sans-serif; overflow: auto; position: relative; }
.artBox p { margin: 10px 0; }
.artBox h1, .artBox h2 { margin: 4px 0; }
.artBox code, .artBox pre { background: rgba(0,128,128,.25); padding: 2px 6px; tab-size: 4; }
.artBox pre { padding: 10px 20px; white-space: pre-wrap; word-wrap: break-word; }
.artBox pre code { padding: 0; background: none; }
.artBox blockquote { margin: 10px 20px; padding: 2px 15px; border-left: 3px solid skyblue; background: rgba(240,248,255,.65); }
.artBox table { border-collapse: collapse; white-space: pre-wrap; box-sizing: border-box; }
.artBox th, .artBox td { padding: 8px 10px; border: 1px solid #999; }
.artBox th { text-align: center; background: #eee; }
.tMid { text-align: center; }
.artBox iframe { width: 500px; height: 300px; border: none; outline: none; }
</style>
<div class="artBox">
<p>JS 生成16进制随机颜色可以非常简单,就一句代码:</p>
<pre><code>const color = '#' + Math.random().toString(16).substring(2, 8);
console.log(color); // → 类似结果:#33ed1f</code></pre>
<p>但当需要可控范围的16进制随机颜色,上述方法无能为力。要实现此功能——</p>
<p><strong>首先</strong>,需要理解16进制颜色的内部结构。本质上,16进制颜色由 R、G、B 即红、蓝、绿三种颜色按一定比例混合而成,每一种单色用16进制两位数表示,不足两位数的前面补零。完整的16进制颜色的表达方式如下:</p>
<blockquote>
<p><strong>#a6cc9f</strong></p>
<p>其中:</p>
<p><code>#</code> 是用来表示16进制的前缀;</p>
<p><code>a6</code> 是 R(红)、<code>cc</code> 是 G(绿)、<code>9f</code> 是B(蓝)</p>
</blockquote>
<p><strong>其次</strong>,需要了解单色分量取值范围,<code>0~255</code>,包含头尾数值。</p>
<p>下面是实现方法:</p>
<p>(一)设计一个取范围值函数,允许设定单色值范围:</p>
<pre><code>const getRdNumFromAr = (ar = ) => {
ar.sort((a, b) => b > a);
const n1 = Math.min(Math.max(ar, 0), 255), n2 = Math.min(Math.max(ar, 0), 255);
return Math.round(Math.random() * (n2 - n1) + n1);
};
</code></pre>
<p>此函数预设了取值范围为 ,没有传参时使用它。函数内部,先排序传参数组,以确保小数在前、大数在后;接着处理数组里面两个数值元素,用 Math.min 和 Math.max 方法确保数值不越界(0~255);最后,用 Math.random() 和 Math.round 方法取得最两个数值之间的随机数、四舍五入,并返回结果给调用者。</p>
<p>(二)设计一个创建16进制颜色的函数,允许配置 RGB 范围:</p>
<pre><code>const rdHexColor = (option) => {
if (!option) option = { r: , g: , b: };
const r = getRdNumFromAr(option.r).toString(16).padStart(2, '0');
const g = getRdNumFromAr(option.g).toString(16).padStart(2, '0');
const b = getRdNumFromAr(option.b).toString(16).padStart(2, '0');
return `#${r}${g}${b}`;
};
</code></pre>
<p>函数首先检测是否有传参,如果没有,创建 RGB 缺省配置;接着分别处理三种单色值,以红色 r 为例加以说明:调用 getRdNumFromAr() 函数处理配置值 r(<code>getRdNumFromAr(option.r)</code>),将其变为16进制(<code>toString(16)</code> 方法),得到的结果如果不足两位的前面补零(<code>patStart()</code> 方法);最后拼凑字串并返回结果。</p>
<p>完整的示例代码:</p>
<pre><code id="hexCode"><style>
#myDiv { margin: auto; margin-top: 40px; width: 400px; height: 240px; border: 1px solid gray; position: relative; }
#myDiv::before { position: absolute; content: attr(data-c); top: -40px; }
</style>
<div id="myDiv" data-c="点击下方矩形生成随机颜色"></div>
<script>
const rdHexColor = (option) => {
if (!option) option = { r: , g: , b: };
const r = getRdNumFromAr(option.r).toString(16).padStart(2, '0');
const g = getRdNumFromAr(option.g).toString(16).padStart(2, '0');
const b = getRdNumFromAr(option.b).toString(16).padStart(2, '0');
return `#${r}${g}${b}`;
};
const getRdNumFromAr = (ar = ) => {
ar.sort((a, b) => b > a);
const n1 = Math.min(Math.max(ar, 0), 255), n2 = Math.min(Math.max(ar, 0), 255);
return Math.round(Math.random() * (n2 - n1) + n1);
};
const setting = {
r: ,
g: ,
b:
};
myDiv.onclick = () => myDiv.style.background = myDiv.dataset.c = rdHexColor(setting);
</script>
</code></pre>
<p>效果如下:</p>
<div id="showDiv" class="tMid"></div>
<p>修改红蓝绿单色分量配置即 setting 对象,就可以拿到预期的颜色范围。</p>
</div>
<script>
const preView = (htmlCode, targetBox) => {
if (targetBox.innerHTML) return;
const iframe = document.createElement('iframe');
iframe.srcdoc = htmlCode;
targetBox.appendChild(iframe);
targetBox.style.display = 'block';
targetBox.onclick = () => {
targetBox.innerHTML = '';
targetBox.style.display = 'none';
}
};
preView(hexCode.innerText, showDiv);
</script> 很实用的知识,谢谢马老师经典讲授{:4_180:} 杨帆 发表于 2026-3-11 18:49
很实用的知识,谢谢马老师经典讲授
这个应用场景还是很广的 马黑黑 发表于 2026-3-11 19:52
这个应用场景还是很广的
是啊,五彩缤纷的世界心之所向,只是运用自如并不容易呢{:4_180:} 杨帆 发表于 2026-3-11 20:03
是啊,五彩缤纷的世界心之所向,只是运用自如并不容易呢
投入就有收获 马黑黑 发表于 2026-3-11 20:29
投入就有收获
至理名言,投入与收获在一起,感恩老师的讲授与指导{:4_180:} 这个例子是拿掉了红色,绿色蓝色也被设定在一定的范围里,即使这样,颜色其实仍然还是很多呢{:4_187:} 红影 发表于 2026-3-11 23:34
这个例子是拿掉了红色,绿色蓝色也被设定在一定的范围里,即使这样,颜色其实仍然还是很多呢
你能看出 setting 配置的含义,太棒了 杨帆 发表于 2026-3-11 22:50
至理名言,投入与收获在一起,感恩老师的讲授与指导
{:4_191:} 马黑黑 发表于 2026-3-13 12:23
你能看出 setting 配置的含义,太棒了
这是在黑黑的讲解里学习的,感谢黑黑夸奖,开心{:4_205:} 红影 发表于 2026-3-15 22:25
这是在黑黑的讲解里学习的,感谢黑黑夸奖,开心
{:4_191:} 马黑黑 发表于 2026-3-16 13:45
干杯{:4_191:} 红影 发表于 2026-3-18 11:35
干杯
谢干
页:
[1]