在脚本中获取CSS颜色属性的真实值

时间:2012-08-07 04:03:48

标签: javascript css

当我在元素的color属性上使用window.getComputedStyle时,它会返回一个带有rgb()rgba()值的字符串,而不管最初用于设置颜色的语法。在Internet Explorer中,当强制使用element.currentStyle时,它显然会返回最初设置的确切颜色字符串(尽管是小写的)。

以下是我的问题的演示:

<div id=el>&nbsp;</div>
<script type="text/javascript">
var el = document.getElementById('el');
el.style.color = 'red';
if (window.getComputedStyle) {
    el.innerHTML = getComputedStyle(el, null).color;
} else {
    el.innerHTML = el.currentStyle.color;
}
</script>

其他浏览器显示“rgb(255,0,0)”。 IE显示“红色”。我想确定真正的RGB或RGBA值。所以我有两个问题:

  1. 有没有办法在IE中获得真正的价值...除了手动解析所有潜在的颜色语法并包括颜色名称到值的映射?
  2. 是否可以依赖其他浏览器的行为?他们应该将值作为rgb()rgba()字符串返回,还是可以返回,例如#ff0000或其他内容?

2 个答案:

答案 0 :(得分:3)

我能说的最好,答案是“不”。在不知道如何解析所有可能的颜色表示的情况下,没有简单的方法来获取IE中的颜色值。当我尝试这样做时,我发现我甚至需要识别所有可能的颜色名称,如blue。这是一个皇家的痛苦,但我确实为它制定了代码。

我的代码试图获取背景颜色,它甚至会查看父对象以找到背景颜色的设置位置(因此它没有完全符合您的要求)并且它使用了YUI版本的getComputedStyle(你可以替换自己的)但这是我使用的代码。它确实处理这些形式的颜色定义:

#fff
#ffffff
transparent
rgb(12,45,99)
rgba(12,45,99,30)
orange

而且,代码:

JFL.GetBackgroundColor = function(o)
{
    var colorNames = {
        aliceblue: 'f0f8ff',
        antiquewhite: 'faebd7',
        aqua: '00ffff',
        aquamarine: '7fffd4',
        azure: 'f0ffff',
        beige: 'f5f5dc',
        bisque: 'ffe4c4',
        black: '000000',
        blanchedalmond: 'ffebcd',
        blue: '0000ff',
        blueviolet: '8a2be2',
        brown: 'a52a2a',
        burlywood: 'deb887',
        cadetblue: '5f9ea0',
        chartreuse: '7fff00',
        chocolate: 'd2691e',
        coral: 'ff7f50',
        cornflowerblue: '6495ed',
        cornsilk: 'fff8dc',
        crimson: 'dc143c',
        cyan: '00ffff',
        darkblue: '00008b',
        darkcyan: '008b8b',
        darkgoldenrod: 'b8860b',
        darkgray: 'a9a9a9',
        darkgreen: '006400',
        darkkhaki: 'bdb76b',
        darkmagenta: '8b008b',
        darkolivegreen: '556b2f',
        darkorange: 'ff8c00',
        darkorchid: '9932cc',
        darkred: '8b0000',
        darksalmon: 'e9967a',
        darkseagreen: '8fbc8f',
        darkslateblue: '483d8b',
        darkslategray: '2f4f4f',
        darkturquoise: '00ced1',
        darkviolet: '9400d3',
        deeppink: 'ff1493',
        deepskyblue: '00bfff',
        dimgray: '696969',
        dodgerblue: '1e90ff',
        feldspar: 'd19275',
        firebrick: 'b22222',
        floralwhite: 'fffaf0',
        forestgreen: '228b22',
        fuchsia: 'ff00ff',
        gainsboro: 'dcdcdc',
        ghostwhite: 'f8f8ff',
        gold: 'ffd700',
        goldenrod: 'daa520',
        gray: '808080',
        green: '008000',
        greenyellow: 'adff2f',
        honeydew: 'f0fff0',
        hotpink: 'ff69b4',
        indianred : 'cd5c5c',
        indigo : '4b0082',
        ivory: 'fffff0',
        khaki: 'f0e68c',
        lavender: 'e6e6fa',
        lavenderblush: 'fff0f5',
        lawngreen: '7cfc00',
        lemonchiffon: 'fffacd',
        lightblue: 'add8e6',
        lightcoral: 'f08080',
        lightcyan: 'e0ffff',
        lightgoldenrodyellow: 'fafad2',
        lightgrey: 'd3d3d3',
        lightgreen: '90ee90',
        lightpink: 'ffb6c1',
        lightsalmon: 'ffa07a',
        lightseagreen: '20b2aa',
        lightskyblue: '87cefa',
        lightslateblue: '8470ff',
        lightslategray: '778899',
        lightsteelblue: 'b0c4de',
        lightyellow: 'ffffe0',
        lime: '00ff00',
        limegreen: '32cd32',
        linen: 'faf0e6',
        magenta: 'ff00ff',
        maroon: '800000',
        mediumaquamarine: '66cdaa',
        mediumblue: '0000cd',
        mediumorchid: 'ba55d3',
        mediumpurple: '9370d8',
        mediumseagreen: '3cb371',
        mediumslateblue: '7b68ee',
        mediumspringgreen: '00fa9a',
        mediumturquoise: '48d1cc',
        mediumvioletred: 'c71585',
        midnightblue: '191970',
        mintcream: 'f5fffa',
        mistyrose: 'ffe4e1',
        moccasin: 'ffe4b5',
        navajowhite: 'ffdead',
        navy: '000080',
        oldlace: 'fdf5e6',
        olive: '808000',
        olivedrab: '6b8e23',
        orange: 'ffa500',
        orangered: 'ff4500',
        orchid: 'da70d6',
        palegoldenrod: 'eee8aa',
        palegreen: '98fb98',
        paleturquoise: 'afeeee',
        palevioletred: 'd87093',
        papayawhip: 'ffefd5',
        peachpuff: 'ffdab9',
        peru: 'cd853f',
        pink: 'ffc0cb',
        plum: 'dda0dd',
        powderblue: 'b0e0e6',
        purple: '800080',
        red: 'ff0000',
        rosybrown: 'bc8f8f',
        royalblue: '4169e1',
        saddlebrown: '8b4513',
        salmon: 'fa8072',
        sandybrown: 'f4a460',
        seagreen: '2e8b57',
        seashell: 'fff5ee',
        sienna: 'a0522d',
        silver: 'c0c0c0',
        skyblue: '87ceeb',
        slateblue: '6a5acd',
        slategray: '708090',
        snow: 'fffafa',
        springgreen: '00ff7f',
        steelblue: '4682b4',
        tan: 'd2b48c',
        teal: '008080',
        thistle: 'd8bfd8',
        tomato: 'ff6347',
        turquoise: '40e0d0',
        violet: 'ee82ee',
        violetred: 'd02090',
        wheat: 'f5deb3',
        white: 'ffffff',
        whitesmoke: 'f5f5f5',
        yellow: 'ffff00',
        yellowgreen: '9acd32'
    };
    function parseSingle(s)
    {
        s = s + s;
        return(parseInt(s, 16));
    }
    var color;
    while (o)
    {
        color = YD.getComputedStyle(o, "backgroundColor");
        if (color && color != "transparent")
        {
            break;
        }
        if (o == document.body)
        {
            color = "#ffffff";
            break;
        }
        o = o.parentNode;
    }
    color = color.replace(/ /g, "").toLowerCase();
    if (colorNames[color])
    {
        color = "#" + colorNames[color];
    }
    var r = 256, g = 256, b = 256;
    if (color.indexOf("#") == 0)
    {
        color = color.slice(1);
        if (color.length == 3)
        {
            r = parseSingle(color.slice(0,1));
            g = parseSingle(color.slice(1,2));
            b = parseSingle(color.slice(2,3));
        }
        else if (color.length == 6)
        {
            r = parseInt(color.slice(0,2), 16);
            g = parseInt(color.slice(2,4), 16);
            b = parseInt(color.slice(4,6), 16);
        }
    }
    else if (color.indexOf("rgb") == 0)
    {
        var results = color.match(/^rgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})/);
        if (results && results.length >= 4)
        {
            r = parseInt(results[1], 10);
            g = parseInt(results[2], 10);
            b = parseInt(results[3], 10);
        }
    }
    var luminance = (0.3 * r + 0.59 * g + 0.11 * b) / 256;
    return({r: r, g: g, b: b, luminance: luminance});
}

答案 1 :(得分:0)

根据建议,我检查了CMS使用queryCommandValue的答案here。相当于CSS'color'而不是'backround-color',我不得不使用'ForeColor'而不是'BackColor',但这种技术似乎非常适合在IE中获得真正的价值。

以下是我的问题中示例的修改后的工作版本:

<div id=el>&nbsp;</div>
<script type="text/javascript">
var el = document.getElementById('el');
el.style.color = 'red';
if (window.getComputedStyle) {
    el.innerHTML = getComputedStyle(el, null).color;
} else {
    var oRG = document.body.createTextRange();
    oRG.moveToElementText(el);
    var iClr = oRG.queryCommandValue('ForeColor');
    el.innerHTML = 'rgb('+(iClr & 0xFF)+','+((iClr & 0xFF00)>>8)+','+((iClr & 0xFF0000)>>16)+')';
}
</script>

我一直在寻找第二个问题的答案,但似乎没有。如果我正确地阅读它,这个页面:http://www.w3.org/TR/css3-color/解释说,对于计算值,浏览器可以返回“六位十六进制值或rgb(...)功能值,alpha值为1 “(?)。它说transparent返回rgba(0,0,0,0)。最后它说,“对于所有其他值,计算值是指定值”。这根本不清楚。例如,它必须使用RGB整数还是可以使用百分比?这些价值观可能存在空间吗?可以保留“指定值”的字母案例吗?那么hsl()hsla()颜色呢?

在实践中,浏览器似乎规范化值以返回rgb(...)rgba(...),红绿蓝为整数,alpha为小数,每个逗号后有一个空格,虽然这似乎没有正式指定。作为例外,如果颜色的alpha值为0,则Firefox似乎返回transparent,而不管其他值或设置方式如何;例如,rgba(255, 0, 255, 0)

因此,如果你可以使用IE,那么获取RGB int的奇怪方法就更简单了。