javascript - Cum să obții valoarea culorii în hex în loc de valoarea RGB?


Folosind următorul jQuery se va obține valoarea RGB a culorii de fundal a unui element:

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

Există vreo modalitate de a obține valoarea hexagonală în loc de RGB?

Răspuns #1

Rezumat

Folosește această funcție curată pe un singur rând, cu suport atât pentru rgb, cât și pentru 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('')}`

Răspuns actualizat în 2021

A trecut mult timp de când am răspuns inițial la această întrebare. Apoi, caracteristici interesante ECMAScript 5 și 2015+ au devenit pe scară largă disponibile în browsere, cum ar fi funcțiile săgeată, Array.map, String.padStart și șirurile șablon. De câțiva ani, este posibil să scrii un rgb2hex cross-browser într-o singură linie:

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

Funcționează utilizând o expresie regulată pentru a obține fiecare cifră din șirul rgb, slice(1) pentru a obține doar cifrele (primul rezultat al match este chiar șirul complet), map pentru a itera prin fiecare cifră, fiecare iterație convertind la Number cu parseInt, apoi înapoi la un String hexazecimal (printr-o conversie în baza 16), adăugând zero dacă este nevoie prin padStart. În final, join fiecare cifră convertită/ajustată într-un String unic începând cu '#'.

Desigur, am putea să îl extindem fără prea mult efort ca o linie unică 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)'))

Și asta e tot. Dar dacă vrei să aprofundezi în lumea veche a JavaScript-ului, continuă să citești.


Răspuns original 2010

Iată soluția mai curată pe care am scris-o bazându-mă pe sugestia lui @Matt:

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

Unele browsere returnează deja culorile în format hexadecimal (începând cu Internet Explorer 8 și versiuni anterioare). Dacă trebuie să gestionezi aceste cazuri, pur și simplu adaugă o condiție în interiorul funcției, așa cum a sugerat @gfrobenius:

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

Dacă folosești jQuery și vrei o abordare mai completă, poți folosi CSS Hooks disponibile încă din jQuery 1.4.3, așa cum am arătat când am răspuns la această întrebare: Pot forța returnările jQuery.css("backgroundColor") pe formatul hexazecimal?

Răspunsul #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];
 }

(Sursă)

Răspuns #3

Majoritatea browserelor par să returneze valoarea RGB atunci când se utilizează:

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

Doar I.E (doar 6 testate până acum) returnează valoarea hexazecimală.

Pentru a evita mesajele de eroare în I.E, ai putea încadra funcția într-o instrucțiune 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]); 
     }
}

Răspunsul #4

Actualizat @ErickPetru pentru compatibilitate 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]);
}

Am actualizat regex-ul pentru a potrivi valoarea alfa dacă este definită, dar fără a o folosi.

Răspunsul #5

Iată o comandă ES6 pe o singură linie care nu folosește 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('');