使用循环

时间:2016-05-09 01:29:20

标签: javascript

我创建了一个颜色滑块(在this library的帮助下),我现在正试图让颜色滑块具有动态渐变。我已成功实现了这一点,但是当我尝试最小化渐变代码(使用循环)时,我遇到了问题。

这是渐变布局。对于每个滑块,都有x种颜色可以创建渐变。然后在滑块的两侧是纯色。我的代码非常重复,所以我尝试创建循环。循环对我来说看起来很丑陋,而且,那里有一个错误,我不确定如何解决。

这就是错误所说的:

  

未捕获的TypeError:无法读取属性' 1'未定义的

这里是rgb颜色空间滑块的代码。 (我还有3个色彩空间。)

setGradient(slider[0], "right", [rgba2cssString(0, rgb.g, rgb.b), rgba2cssString(255, rgb.g, rgb.b)]);
setGradient(slider[1], "right", [rgba2cssString(rgb.r, 0, rgb.b), rgba2cssString(rgb.r, 255, rgb.b)]);
setGradient(slider[2], "right", [rgba2cssString(rgb.r, rgb.g, 0), rgba2cssString(rgb.r, rgb.g, 255)]);

slider[0].previousElementSibling.style.backgroundColor = rgba2cssString(0, rgb.g, rgb.b);
slider[0].nextElementSibling.style.backgroundColor = rgba2cssString(255, rgb.g, rgb.b);
slider[1].previousElementSibling.style.backgroundColor = rgba2cssString(rgb.r, 0, rgb.b);
slider[1].nextElementSibling.style.backgroundColor = rgba2cssString(rgb.r, 255, rgb.b);
slider[2].previousElementSibling.style.backgroundColor = rgba2cssString(rgb.r, rgb.g, 0);
slider[2].nextElementSibling.style.backgroundColor = rgba2cssString(rgb.r, rgb.g, 255);

这是尝试的缩小版本(适用于所有颜色空间(" Lab"是颜色空间))。如果使用循环也生成gradientObject会有所帮助。

var gradientObject = {
    rgb: [[[0, rgb.g, rgb.b], [255, rgb.g, rgb.b]],
        [[rgb.r, 0, rgb.b], [rgb.r, 255, rgb.b]],
        [[rgb.r, rgb.g, 0], [rgb.r, rgb.g, 255]]],

    hsl: [[[60, hsl.s, hsl.l], [120, hsl.s, hsl.l], [180, hsl.s, hsl.l], [300, hsl.s, hsl.l], [360, hsl.s, hsl.l]],
        [[hsl.h, 0, hsl.l], [hsl.h, 100, hsl.l]],
        [[hsl.h, hsl.s, 0], [hsl.h, hsl.s, 50], [hsl.h, hsl.s, 100]]],

    hsv: [[[0, hsv.s, hsv.v], [60, hsv.s, hsv.v], [120, hsv.s, hsv.v], [180, hsv.s, hsv.v], [300, hsv.s, hsv.v], [360, hsv.s, hsv.v]],
        [[hsv.h, 0, hsv.v], [hsv.h, 100, hsv.v]],
        [[hsv.h, hsv.s, 0], [hsv.h, hsv.s, 50], [hsv.h, hsv.s, 100]]],

    Lab: [[[0, Lab.a, Lab.b], [100, Lab.a, Lab.b]],
        [[Lab.L, -128, Lab.b], [Lab.L, 128, Lab.b]],
        [[Lab.L, Lab.a, -128], [Lab.L, Lab.a, 128]]],

    alpha: [[[255, 255, 255, 0], [rgb.r, rgb.g, rgb.b, 1]]]
};

var sliderIndex = 0;
for (var colorSpaceGradient in gradientObject) {
    if (!gradientObject.hasOwnProperty(colorSpaceGradient)) return;

    var currentColorSpaceGradient = gradientObject[colorSpaceGradient],
        currentSlidersArray = [];

        for (var i = 0; i < currentColorSpaceGradient.length; i++) {
            var colorSliderGradient = currentColorSpaceGradient[i],
                colorSliderGradientArray = [];

            for (var x = 0; x < colorSliderGradient.length; x++) {
                console.log(colorSliderGradient[x]);
                colorSliderGradientArray.push(toCSSstring[colorSpaceGradient](colorSliderGradient[x]));
            }
            setGradient(slider[sliderIndex], 'right', colorSliderGradientArray);
            sliderIndex++;
        }

}

完整代码:(第95 - 204行的相关代码

codePen

我的问题是,如何在不出错的情况下最小化代码?

1 个答案:

答案 0 :(得分:0)

如果不能很好地了解代码的内部工作原理,我可以在hsva2cssString函数中看到一些潜在的问题。

我怀疑的一件事是给你带来麻烦的是从第365行开始的if-chain:

if (typeof h === 'object') { /*something*/ }
else if (Array.isArray(h)) { /*something else*/ }

你永远不会超越第一个条款。

javascript的一个小怪癖是数组仍被视为对象。因此,即使h是一个数组,第一个if块仍然会通过。尝试运行typeof [],你会明白我的意思。你有正确的想法使用Array.isArray,问题是你永远不会达到那个代码。我建议切换这两个条款的顺序,或者最有可能完全删除第一个条款,原因如下:

在第376行,您对myColor.convertColor的调用是作为数组传递hsvObject(因为第一个if子句)。该函数似乎期望第一个参数作为一个对象,而不是一个数组,它会让你得到你提到的错误。

此外,当函数期望alpha的第四个值时,你的hsv数组有三个元素。我可以预见那里的问题,但我不知道解决方案是在改变数组本身,还是改变函数处理数组的方式。

我很谨慎地在没有更好地了解您的代码的情况下为您提供直接的解决方案,但我认为如果您仔细查看if中的hsva2cssString块,您会发现原因是什么错误。