Vyhledávání na webu

JavaScript - Jak získat hodnotu hexadecimální barvy místo RGB?


Použití následujícího jQuery získá RGB hodnotu barvy pozadí prvku:

$('#selector').css('backgroundColor');

Existuje způsob, jak získat hexadecimální hodnotu místo RGB?

Odpověď č. 1

Shrnutí

Použijte tuto čistou jednoradkovou funkci s podporou pro rgb i rgba:

const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

Aktualizovaná odpověď z roku 2021

Už uplynulo hodně času od té doby, co jsem původně odpověděl na tuto otázku. Tehdy se postupně staly dostupnými v prohlížečích skvělé funkce ECMAScript 5 a 2015+, jako jsou šipkové funkce, Array.map, String.padStart a template strings. Už několik let je možné napsat multiplatformní jednorázový rgb2hex:

const rgb2hex = (rgb) => `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}`

// Use as you wish...
console.log(rgb2hex('rgb(0,0,0)'))
console.log(rgb2hex('rgb(255, 255, 255)'))
console.log(rgb2hex('rgb(255,0,0)'))
console.log(rgb2hex('rgb(38, 170, 90)'))

Funguje to tak, že používá regulární výraz k získání každé číslice uvnitř řetězce rgb, slice(1) k získání pouze číslic (první výsledek match je samotný celý řetězec), map k iteraci přes každou číslici, přičemž každá iterace převádí na Number pomocí parseInt, a poté zpět na hexadecimální String (přes převod se základnou 16), přidáním nuly, pokud je potřeba, pomocí padStart. Nakonec se join každá převedená/upravená číslice do jednoho jedinečného String, začínajícího '#'.

Samozřejmě bychom to mohli rozšířit bez větší námahy jako jednorádkový rgba2hex:

const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

// Now it doesn't matter if 'rgb' or 'rgba'...
console.log(rgba2hex('rgb(0,0,0)'))
console.log(rgba2hex('rgb(255, 255, 255)'))
console.log(rgba2hex('rgb(255,0,0)'))
console.log(rgba2hex('rgb(38, 170, 90)'))
console.log(rgba2hex('rgba(255, 0, 0, 0.5)'))
console.log(rgba2hex('rgba(0,255,0,1)'))
console.log(rgba2hex('rgba(127,127,127,0.25)'))

A to je vše. Ale pokud chcete proniknout hlouběji do světa staré školy JavaScriptu, pokračujte ve čtení.


Původní odpověď z roku 2010

Zde je čistší řešení, které jsem napsal na základě @Mattova návrhu:

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]);
}

Některé prohlížeče již vracejí barvy jako hexadecimální (od Internet Exploreru 8 a nižších). Pokud potřebujete tyto případy řešit, stačí do funkce přidat podmínku, jak @gfrobenius navrhl:

function rgb2hex(rgb) {
    if (/^#[0-9A-F]{6}$/i.test(rgb)) return 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]);
}

Pokud používáte jQuery a chcete úplnější přístup, můžete použít CSS Hooky dostupné od jQuery 1.4.3, jak jsem ukázal při odpovědi na tuto otázku: Mohu vynutit, aby jQuery.css("backgroundColor") vracelo hodnotu v hexadecimálním formátu?

Odpověď č. 2

var hexDigits = new Array
        ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 

//Function to convert rgb color to hex format
function rgb2hex(rgb) {
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

function hex(x) {
  return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
 }

(Zdroj)

Odpověď #3

Většina prohlížečů se zdá vracet hodnotu RGB při použití:

$('#selector').css('backgroundColor');

Pouze I.E (zatím testováno jen 6) vrací hexadecimální hodnotu.

Aby se v I.E. zabránilo chybovým hlášením, můžete funkci zabalit do příkazu if:

function rgb2hex(rgb) {
     if (  rgb.search("rgb") == -1 ) {
          return rgb;
     } else {
          rgb = rgb.match(/^rgba?\((\d+),\s*(\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]); 
     }
}

Odpověď č. 4

Aktualizováno @ErickPetru pro kompatibilitu rgba:

function rgb2hex(rgb) {
    rgb = rgb.match(/^rgba?\((\d+),\s*(\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]);
}

Aktualizoval jsem regex tak, aby odpovídal hodnotě alfa, pokud je definována, ale nepoužíval ji.

Odpověď č. 5

Tady je ES6 jednorázek, který nepoužívá jQuery:

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => parseInt(color).toString(16).padStart(2, '0')).join('');

Související články