背景颜色十六进制转换为JavaScript变量

36

我对JavaScript和jQuery有点陌生,现在我遇到了一个问题:

我需要将一些数据发送到PHP,其中一部分数据需要是div X的背景颜色十六进制值。

jQuery有css("background-color")函数,可以将背景的RGB值获取到JavaScript变量中。

CSS函数似乎返回这样一个字符串:rgb(0, 70, 255)。

我找不到任何获取背景颜色的十六进制值的方法(即使它在CSS中被设置为十六进制)。

因此,似乎我需要进行转换。我找到了一个将RGB转换为十六进制的函数,但需要使用三个不同的变量r、g和b来调用它。所以我需要将字符串rgb(x,xx,xxx)解析成var r=x;var g=xx;var b=xxx;的形式。

我尝试过用JavaScript解析字符串,但我并没有真正理解正则表达式的东西。

是否有办法获取div的背景颜色作为十六进制呢,或者可以将该字符串转换为三个不同的变量吗?

10个回答

61

试着这样做:

var rgbString = "rgb(0, 70, 255)"; // get this in whatever way.

var parts = rgbString.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"]

delete (parts[0]);
for (var i = 1; i <= 3; ++i) {
    parts[i] = parseInt(parts[i]).toString(16);
    if (parts[i].length == 1) parts[i] = '0' + parts[i];
} 
var hexString ='#'+parts.join('').toUpperCase(); // "#0070FF"

回答下面评论中的问题:

我正在尝试修改正则表达式,以处理rgb和rgba,具体取决于我得到的是哪个。有什么提示吗?谢谢。

我不确定在这个问题的上下文中是否有意义(因为你不能用十六进制表示一个rgba颜色),但我想可能还有其他用途。无论如何,您可以将正则表达式更改为以下内容:

/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(0\.\d+))?\)$/

示例输出:

var d = document.createElement('div');
d.style.backgroundColor = 'rgba( 255,  60, 50, 0)';

/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(1|0\.\d+))?\)$/.exec(d.style.backgroundColor);

// ["rgba(255, 60, 50, 0.33)", "255", "60", "50", "0.33"]

3
零件不是会是["rgb(0, 70, 255)","0","70","255"]吗? - Matthew Crumley
5
我喜欢StackOverflow。谢谢,我不想自己解决这个问题。 :-P - KyleFarris
2
@Neal 或其他遇到这个问题的人:在 IE 中,jquery 1.4.4 返回十六进制代码而不是 RGB 字符串。因此,“parts”为空,因为正则表达式不匹配,从而导致使用“parts”时出错。我必须在删除之前添加一个检查,并返回原始字符串(如果“parts”为空)。 - JeffB
2
@nickf之前忘了感谢你。顺便说一下,我添加了/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(1|0|0\.\d+))?\)$/在末尾附近加上了|0来检查alpha是否为0而不是0.x。 - fortuneRice
2
@fortuneRice 我认为应该是(1|0|0?\.d+),因为.3是有效的。 - nickf
显示剩余5条评论

10
如果您有jQuery可用,这是我刚想出来的超紧凑版本。
var RGBtoHEX = function(color) {
  return "#"+$.map(color.match(/\b(\d+)\b/g),function(digit){
    return ('0' + parseInt(digit).toString(16)).slice(-2)
  }).join('');
};

注:该代码实现将RGB颜色值转换为十六进制颜色值。

现在我们甚至不需要jQuery来进行映射。这是原始版本:var RGBtoHEX = function(color) { return "#"+(color.match(/\b(\d+)\b/g).map(function(digit){ return ('0' + parseInt(digit).toString(16)).slice(-2) })).join(''); }; - oriadam

8

您也可以使用rgb设置CSS颜色,例如:

background-color: rgb(0, 70, 255);

这是有效的CSS,不用担心。


编辑:如果你确实需要转换,可以查看nickf的答案


如果以后某个网页需要恢复颜色,那么为什么要进行任何转换工作呢 :) - Anurag

5

我前一段时间找到了另一个函数(by R0bb13)。它没有正则表达式,所以我不得不从nickf那里借来才能使它正常工作。我之所以发布它,是因为这是一种有趣的方法,不使用if语句或循环即可给出结果。此外,该脚本将十六进制值与#一起返回(当时我使用的Farbtastic插件需要它)

//Function to convert hex format to a rgb color
function rgb2hex(rgb) {
 var hexDigits = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 function hex(x) {
  return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
 }
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

// call the function: rgb( "rgb(0, 70, 255)" );
// returns: #0046ff

注意:nickf的脚本得到的十六进制结果应该是0046ff而不是0070ff,但这并不重要:P
更新,另一种更好的替代方法:
function rgb2hex(rgb) {
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 function hex(x) {
  return ("0" + parseInt(x).toString(16)).slice(-2);
 }
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

我更愿意将函数hex(x)移出函数rgb2hex的作用域以提高性能。无论如何,这是一个不错的干净解决方案,感谢分享。请看下面的代码,我想听听你的意见。 - Marco Demaio

3

使用JQuery...

var cssColorToHex = function(colorStr){
    var hex = '#';
    $.each(colorStr.substring(4).split(','), function(i, str){
        var h = ($.trim(str.replace(')',''))*1).toString(16);
        hex += (h.length == 1) ? "0" + h : h;
    });
    return hex;
};

1

ffee66fb0在CSS中不是有效的颜色。也许你应该先尝试一下。 - Derek 朕會功夫

1
这个方案怎么样?函数stringRGB2HEX返回输入字符串的副本,其中所有格式为“rgb(r,g,b)”的颜色出现都被替换为十六进制格式“#rrggbb”。
   //function for private usage of the function below
   //(declaring this one in global scope should make it faster rather than 
   //declaraing it as temporary function inside stringRGB2HEX that need to be
   //instantieted at every call of stringRGB2HEX
   function _rgb2hex(rgb_string, r, g, b) 
   {
      //VERY IMPORTANT: by adding (1 << 24) we avoid 'rgb(0, 0, 0)' to be mistakenly converted into '#0'
      var rgb = (1 << 24) | (parseInt(r) << 16) | (parseInt(g) << 8) | parseInt(b); //same thing of: ( r + (256 * g) + (65536 * b) + 16777216)
      //toString(16) specify hex 16 radix, works only for numbers [source: http://msdn.microsoft.com/en-us/library/dwab3ed2(v=VS.85).aspx]   
      return '#' + rgb.toString(16).substr(1); //substr(1) because we have to remove the (1 << 24) added above
   }

   function stringRGB2HEX(string)
   {
      if(typeof string === 'string')
         string = string.replace(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/g, _rgb2hex);
      return string;
   }

这个函数还可以将像 background 这样的复杂样式中的 RGB 颜色转换。

例如,style.background 的值为 "none no-repeat scroll rgb(0, 0, 0)",只需使用 stringRGB2HEX(style.background) 即可轻松将其转换为 "none no-repeat scroll #000000"


1
这些解决方案在Chrome中会失败,因为它返回background-color的rgba(x,x,x,x)。
编辑:这并不一定是真的。根据您的操作,Chrome仍将使用rgb()设置背景。只要没有应用alpha通道,Chrome就会响应rgb而不是rgba。

0

这里有一个方法,允许你使用$(selector).getHexBackgroundColor()轻松地返回十六进制值:

$.fn.getHexBackgroundColor = function() {
    var rgb = $(this).css('background-color');
    rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    function hex(x) {return ("0" + parseInt(x).toString(16)).slice(-2);}
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

0

提供的链接解决方案是错误的,因为它将 "rgb(0, 0, 0)" 转换为 "#0" 而不是 "#000000",原因是如果要移位的值为零,则 << 运算符不会移位。 - Marco Demaio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接