【问题标题】:Javascript converting hex values automatically [duplicate]Javascript自动转换十六进制值[重复]
【发布时间】:2013-04-21 04:08:35
【问题描述】:

目前我在使用这段非常简单的代码时遇到了一些问题:field.style.backgroundColor="#ffffff"; 直到现在它对我来说效果很好,但就在最近我注意到在 webkit 中,十六进制值总是转换为像rgb(255, 255, 255) 这样的 rgb 值。通常这不是问题,但我稍后需要在创建图像的 php 脚本中使用十六进制值。将它们转换回来只会减慢整个过程。所以我真正的基本问题是如何避免获得那些烦人的 rgb 值。

【问题讨论】:

标签: javascript colors background


【解决方案1】:

您可以将值拆分为各个部分,将每个数字转换为十六进制,然后返回格式化字符串,例如:

// convert rgb colour values to hex, e.g. rgb(255, 255, 255) to #ffffff;
function rgbToHex(rgb) {
  var re = /^rgb\(.*\)$/;
  var bits;
  function z(n){return (n<10?'0':'') + n;}

  if (re.test(rgb)) {
    bits = rgb.match(/\d+/g);
    return '#' + z((+bits[0]).toString(16)) + 
                 z((+bits[1]).toString(16)) +
                 z((+bits[2]).toString(16));
  }
  return rgb;
}

alert(rgbToHex('rgb(255, 255, 255)')); // #ffffff   
alert(rgbToHex('rgb(0, 0, 0)')); // #000000
alert(rgbToHex('rgb(100, 230, 90)')); // #64e65a

您可能需要在测试正则表达式上添加一个 i 标志,以防某些浏览器返回“RGB(...)”。

编辑

根据 Xotic750 的帖子,z 函数应该是:

function z(n){return (n.length == 1?'0':'') + n;}

一个不太严格的正则表达式也可能适合:

  var re = /^rgb/i;

另一个失败是垃圾输入,垃圾输出的情况。如果需要,可以修改正则表达式以在“rgb (”中留出一个空格。更新的版本是:

function rgbToHex(rgb) {
    var re = /^rgb/i;
    var bits = rgb.match(/\d+/g);;

    function z(n) {
        return (n.length == 1? '0' : '') + n;
    }

    if (re.test(rgb) && bits.length == 3) {
        return '#' + z((+bits[0]).toString(16))
                   + z((+bits[1]).toString(16))
                   + z((+bits[2]).toString(16));
    }
    return rgb;
}

剩下的唯一选择是如果测试失败,它应该返回原始字符串还是未定义?

【讨论】:

  • 天哪,这个测试会发生什么?一切似乎都有些破碎。 jsfiddle.net/Xotic750/QYqCy
  • @Xotic750——感谢测试用例,正则表达式测试的小改动和 z 函数修复了除最后一种情况外的所有情况,即 gi/go 的情况.应该用什么值代替缺失的十六进制值?或者如果只找到两个术语,它应该返回 undefined 还是原始字符串?
  • 我返回 undefined 因为输入的格式不正确。但这只是我的决定。以下是最新代码的测试用例:jsfiddle.net/Xotic750/zGhAj
【解决方案2】:

编写自己的转换器实际上相当简单,而且计算速度非常快,既然已经安装了充气轮胎,为什么还要重新发明轮子? :) 看看colours javascript 库。

好的,所以库不是你的事,这里有一个函数可以帮你做。

var a = "rgb(10, 128, 255)";
var b = "rgb( 10, 128, 255)";
var c = "rgb(10, 128, 255 )";
var d = "rgb ( 10, 128, 255 )";
var e = "RGB ( 10, 128, 255 )";
var f = "rgb(10,128,255)";
var g = "rgb(10, 128,)";

var rgbToHex = (function () {
    var rx = /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;

    function pad(num) {
        if (num.length === 1) {
            num = "0" + num;
        }

        return num;
    }

    return function (rgb, uppercase) {
        var rxArray = rgb.match(rx),
            hex;

        if (rxArray !== null) {
            hex = pad(parseInt(rxArray[1], 10).toString(16)) + pad(parseInt(rxArray[2], 10).toString(16)) + pad(parseInt(rxArray[3], 10).toString(16));

            if (uppercase === true) {
                hex = hex.toUpperCase();
            }

            return hex;
        }

        return;
    };
}());

console.log(rgbToHex(a));
console.log(rgbToHex(b, true));
console.log(rgbToHex(c));
console.log(rgbToHex(d));
console.log(rgbToHex(e));
console.log(rgbToHex(f));
console.log(rgbToHex(g));

开启jsfiddle

这里是jsperfs

【讨论】:

    【解决方案3】:

    难道你不能直接将值解释为 php 中的十六进制值而不需要对其进行转换吗? 实际上我不知道 JavaScript 到底是什么给你的,但如果它只是单个值,则以十六进制解释它们并将它们连接起来。

    不应该有性能损失。

    问候

    【讨论】:

    • 我必须将大约一百个颜色值从 rgb 转换为 hex。我应该如何在不使用任何代码的情况下将值 rgb(255,255,255) 解释为#ffffff?对我来说真的没有意义......
    猜你喜欢
    • 2018-03-08
    • 2013-06-16
    • 2013-06-13
    • 2017-12-30
    • 1970-01-01
    • 2017-03-19
    • 2014-10-28
    • 2015-11-11
    • 2019-01-27
    相关资源
    最近更新 更多