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('');
