JavaScript缩短重复代码以生成随机CSS颜色

时间:2016-04-27 15:26:47

标签: javascript jquery dry

我决定毫无理由地制作一个随机的十六进制颜色生成器。它工作正常,但需要写

var value1 = hexArray[Math.floor(Math.random() * hexArray.length)];" 6次。我该怎么办呢,所以我不这样做?如果我做这样的事情

var rand1 = rand2 = rand3 ect. = hexArray[Math.floor(Math.random() * hexArray.length)];它会打印出所有具有相同数字/字母的值。有什么建议吗?

    var hexArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
    var rand1 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var rand2 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var rand3 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var rand4 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var rand5 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var rand6 = hexArray[Math.floor(Math.random() * hexArray.length)];
    var array2 = [rand1, rand2, rand3, rand4, rand5, rand6]
    var value = "#" + array2.join("");

    //ignore this
    $(document).ready(function() {
      $("body").css("background-color", value);
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

4 个答案:

答案 0 :(得分:4)

您无需单独生成每个十六进制字符。只需生成一个随机数0和2 ^ 24并将其转换为十六进制:

var pad = "00000"
var random = Math.floor(Math.random() * (0x1000000))
var randomHex = random.toString(16)
var color = "#" + pad.substring(0, 6 - randomHex.length) + randomHex

更新:浏览答案here,有一些不错的技巧但除了接受的答案之外,颜色要么不是随机的,要么是正确的填充,要么是太长。这是另一个在两个方面都应该正确的版本:

var random = Math.floor(Math.random() * (1<<24))
var color = "#" + ("00000" + random.toString(16)).substr(-6)

答案 1 :(得分:3)

评论已经提供了简短的答案,但我将在这里详细说明我们如何做到这一点。

第1部分:

var rand1 = hexArray[Math.floor(Math.random() * hexArray.length)];
var rand2 = hexArray[Math.floor(Math.random() * hexArray.length)];
var rand3 = hexArray[Math.floor(Math.random() * hexArray.length)];
var rand4 = hexArray[Math.floor(Math.random() * hexArray.length)];
var rand5 = hexArray[Math.floor(Math.random() * hexArray.length)];
var rand6 = hexArray[Math.floor(Math.random() * hexArray.length)];

可以将此部分更改为使用数组和循环。这可以做的一个巨大的赠品是你的变量名中有序号。但是,因为数组通常是从零开始的,所以我不会使用1-6而是使用0-5作为索引。在我的循环中,我计算一个从0到5的变量(尽管为了便于阅读,我正在检查它是< 6而不是<= 5 - 很明显它运行了6次)并填充数组。像这样:

var rand = [];
for(var i = 0; i < 6; i++) {
    rand[i] = hexArray[Math.floor(Math.random() * hexArray.length)];
}

然后我们可以改变这个......

var array2 = [rand1, rand2, rand3, rand4, rand5, rand6];

......对此:

var array2 = [rand[0], rand[1], rand[2], rand[3], rand[4], rand[5]];

...它没有多大意义,可以被另一个循环取代:

for(var i = 0; i < rand.length; i++) array2[i] = rand[i];

现在这基本上只是将整个数组rand复制到array2,因此我们可以将其简化为:

var array2 = rand;

好的,但现在总的来说看起来像这样:

var rand = [];
for(var i = 0; i < 6; i++) {
    rand[i] = hexArray[Math.floor(Math.random() * hexArray.length)];
}
var array2 = rand;

应该很清楚我们可以从一开始就使用array2,或者 - 更有意义,因为变量名称更有意义 - 我们可以继续使用rand而不是创建新数组array2,所以我们会改变这个......

var value = "#" + array2.join("");

......对此:

var value = "#" + rand.join("");

作为最后的改进,我们不是一直指定我们想要在上面的循环中创建的数组元素(rand[i] = ...),而是继续推进将自动创建的数组(rand.push(...))每次增加ID的新元素:

var rand = [];
for(var i = 0; i < 6; i++) {
    rand.push(hexArray[Math.floor(Math.random() * hexArray.length)]);
}

所以,在这一点上,代码看起来像这样:

&#13;
&#13;
var hexArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
var rand = [];
for(var i = 0; i < 6; i++) {
    rand.push(hexArray[Math.floor(Math.random() * hexArray.length)]);
}
var value = "#" + rand.join("");

//ignore this
$(document).ready(function() {
  $("body").css("background-color", value);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

这应该已经回答了你的初步问题,因为它删除了重复。但是等等,我们还能做更多的事情!

第2部分:

您正在使用hexArray执行的操作实际上是尝试生成随机十六进制数字。现在我把它放到这句话中,应该很清楚,实际上我们可以用更简单的方式做到这一点:生成一个随机值并将其转换为十六进制表示形式!

可以使用Math.random()生成随机值,0.29283543将输出大于或等于零且小于1的随机值(例如0.917240.18283123255Math.random() ,你明白了。)

为了得到零和另一个值之间的随机数,我们可以将Math.random() * 16的结果乘以独有的最大值,在我们的例子中是16。

3.182372会给出14.22229355.190023Math.floor等数字,这几乎是我们想要的数字,但我们只想得到整数(不含小数部分) )。我们通过将结果反馈到Math.floor(Math.random() * 16)向下舍入来得到此结果,因此3会提供145hexArray.length之类的内容,这正是我们所需要的

这基本上就是你已经做过的事情,因为16someArray[Math.floor(Math.random() * someArray.length)]我还是解释了它,因为有人可能会开始使用14成语了解它是如何工作的。

然而,当我们将数字填入字符串时,它们将是十进制的。我们希望它们采用十六进制表示形式,以便前一个示例中的e变为toString。这可以通过在数字上调用var number = 123; console.log(number.toString(16));方法来完成,该方法采用指定数字基数的可选参数(例如,7b将输出Math.floor(Math.random() * 16).toString(16) )。

因此,我们可以使用以下方法获得随机十六进制数字:

var hexArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
var rand = [];
for(var i = 0; i < 6; i++) {
    rand.push(hexArray[Math.floor(Math.random() * hexArray.length)]);
}

因此,让我们再次简化之前的代码,并更改此内容......

var rand = [];
for(var i = 0; i < 6; i++) {
    rand.push(Math.floor(Math.random() * 16).toString(16));
}

......对此:

var rand = [];
for(var i = 0; i < 6; i++) {
    rand.push(Math.floor(Math.random() * 16).toString(16));
}
var value = "#" + rand.join("");

//ignore this
$(document).ready(function() {
  $("body").css("background-color", value);
});

所以整个代码现在看起来像这样:

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;
#
&#13;
&#13;
&#13;

但是,嘿,我们还没有完成!

第3部分:

让我们回顾一下代码目前的作用:

  1. 它会创建一个数组。
  2. 它将6个随机十六进制数字推入数组。
  3. 它连接数组并预先设置Math.random(Math.floor() * 16).toString(16),以创建CSS颜色值。
  4. 它在CSS中设置背景颜色。
  5. 现在可以进一步简化1-3点,因为最后,我们基本上创建了一个随机6位十六进制值

    在第2步中,我们开始使用16创建0到16之间的随机值(排他地)并将其转换为十六进制表示。为清楚起见,让我将此处的第一个0x更改为十六进制(如果您不知道,可以通过为Math.random(Math.floor() * 0x10).toString(16) 添加前缀来使用十六进制文字):

    Math.random(Math.floor() * 0x1000000).toString(16)
    

    我们可以使用相同的机制来创建0到0xFFFFFF(包含)之间的随机值,即0和0x1000000(独占),如下所示:

    E81C

    这将给我们随机值,如0x29F3D5(十进制2749397),0xC720FE(十进制13050110)等。

    这听起来确实是我们需要的,对吧?好吧,差不多。随机值可以小于0x100000,在这种情况下,它们将具有少于6个数字,例如, 0xE81C或0x12345!

    这意味着我们必须用左边的零填充它,总是有6位数,不能少。不幸的是,没有强大的内置方法可以做到这一点,所以我们必须手动添加零。因此,当随机函数为我们提供字符串00E81C时,我们必须添加两个零来使其成为6 - length

    当然我们可以计算现有字符串的长度并计算"00000" + Math.floor(Math.random() * 0x1000000).toString(16) ,然后添加那么多的零...但是有一种更简单的方法可以做到。因为我们知道我们总是至少有一个数字,最多有6个数字,而且我们总是想要6,这意味着我们必须根据现有长度添加0到5个零。我们现在可以假设最坏的情况,并且总是添加5个零

    substr

    当然这意味着字符串现在通常太长(6到11个字符之间),但是我们可以通过仅使用最后6个字符来解决这个问题,这可以使用字符串方法substr来完成。由于确切地说明调用"hello".substr(-3)"的不同方式会使这个已经很长的回答太长,我只需链接到the documentation for this method以进一步阅读并告知您可以使用负值作为参数从右侧中提取一定数量的字符。例如,llo会为您提供("00000" + Math.floor(Math.random() * 0x1000000).toString(16)).substr(-6)

    因此,知道这一点,我们可以构建代码,它总是再次为我们提供6个随机十六进制数字:

    .substr

    请注意,我必须在substr之前添加parens,否则只会在+的右侧部分调用rand方法,而不是整个事件。

    让我们采用这种新方法。我们可以替换整个rand.join("")数组和var value = "#" + ("00000" + Math.floor(Math.random() * 0x1000000).toString(16)).substr(-6); //ignore this $(document).ready(function() { $("body").css("background-color", value); });部分。代码现在看起来像这样:

    &#13;
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    &#13;
    {{1}}
    &#13;
    &#13;
    &#13;

    这就是我们登陆the code suggested by Niet the Dark Absol in the comments的方式!

    我知道这是一个非常冗长的答案,也许你已经知道了大部分内容,但也许不是。也许你或其他读者抓住了我们如何落实这一结果或者可能采取的其他优化步骤。这就是我写这篇演练的原因。 :)

答案 2 :(得分:2)

var hexArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
var array2 = [];
for (i = 0; i <= 5; i++) {
  array2.push(hexArray[Math.floor(Math.random() * hexArray.length)]);
}
var value = "#" + array2.join("");

$('div').css("background-color", value);

答案 3 :(得分:0)

这对我来说是最简单的。一行,简单。

    Var randomColor = "#" + Math.floor(Math.random() * parseInt(0x1000000)).toString(16);