2

I am trying to create a jQuery hook which will read and set all colors as hex values instead of RGB. I have found a hook that will properly read the color as HEX but I am not sure on how to modify it to write CSS colors as HEX.

So for example I would like $("h1").css('color', '#333333'); to inline style h1's with "style='color:#333333;'" instead of the current RGB equivalent. The hook I am using to return read colors as hex is:

$.cssHooks.color = {
get: function(elem) {
    if (elem.currentStyle)
        var bg = elem.currentStyle["color"];
    else if (window.getComputedStyle)
        var bg = document.defaultView.getComputedStyle(elem,
            null).getPropertyValue("color");
    if (bg.search("rgb") == -1)
        return bg;
    else {
        bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
        function hex(x) {
            return ("0" + parseInt(x).toString(16)).slice(-2);
        }
        return "#" + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
    }
}}

Update

I was able to accomplish it in a super roundabout way by getting all the elements styles converting any colors to HEX and the rebuilding the styles and setting it via $(elm).attr(style, styles); Seems very hacky and convoluted but it works.

Kupe
  • 665
  • 7
  • 13
  • 5
    Not sure I get it, but it's up to the browser what is actually set, and more importantly returned, so there's no guarantee the browser will return rgb or rgba, or for older browsers even hex ? – adeneo Aug 27 '15 at 20:31
  • I am creating a tool which creates HTML for emails. Since a lot of email clients don't handle RGB colors well I want all colors set to be in HEX format. Right now the tool is just for myself and I am using the latest version of Chrome to test. – Kupe Aug 27 '15 at 20:48

2 Answers2

2

This method seems to work for me, but it assumes a well formatted string. You could add your checks to this function:

function rgb_to_hex(rgb_color) {
    if (!rgb_color) return ''
    return rgb_color
        .replace(/.*rgba?\(([^(]+)\).*/gi, '$1')
        .split(',')
        .splice(0,3)
        .reduce(function(acc, cur) { return acc+format_hex(cur) }, '');
}

function format_hex(ns) {
    var v;
    return isNaN(v = parseInt(ns)) ? '' : ('00' + v.toString(16)).substr(-2);
}

var v,
    color1 = (v = rgb_to_hex('rgb(0,0,0)')) !== '' ?  '#' + v : '',
    color2 = (v = rgb_to_hex('rgb(0,255,0)')) !== '' ?  '#' + v : '',
    color3 = (v = rgb_to_hex('rgba(123,39,12, .1)')) !== '' ?  '#' + v : '',
    color4 = (v = rgb_to_hex()) !== '' ?  '#' + v : '';
    color5 = (v = rgb_to_hex('gobbledegook')) !== '' ?  '#' + v : '';
console.log(color1); // '#000000'
console.log(color2); // '#00ff00'
console.log(color3); // '#7b270c'
console.log(color4); // ''
console.log(color5); // ''

Also, this portion:

if (elem.currentStyle)
    var bg = elem.currentStyle["color"];
else if (window.getComputedStyle)
    var bg = document.defaultView.getComputedStyle(elem, null)
        .getPropertyValue("color");

should be something like:

var bg = '';
if (elem.currentStyle) {
    bg = elem.currentStyle["color"];
} else if (window.getComputedStyle) {
    bg = document.defaultView.getComputedStyle(elem, null)
        .getPropertyValue("color");
}

because bg might not be defined.

Alex Luecke
  • 197
  • 2
  • 9
1

The problem you have is that jQuery doesn't write what you wants, but what it understands. You can "force" the code do what you want like this:

$('h1').css('color', '');
$('h1').attr('style', $('h1').attr('style') + 'color: #FFEE02');

You must use the first line in order to don't make your html code grow so much, and in the second line, you set the color over the html.