1

Currently i'd like to read out the background color of a css through javascript to update a canvas with the desired color. So far i get it to work by creating a dummy object within html that holds that css from which i can read it:

The CSS content:

.logmessage-debug {
    color: #fff;
    background-color: #999999;
}

.logmessage-info {
    color: #fff;
    background-color: #5cb85c;
}

.logmessage-warn {
    color: #fff;
    background-color: #f0ad4e;
}

.logmessage-error {
    color: #fff;
    background-color: #d9534f;
}

.logmessage-fatal {
    color: #fff;
    background-color: #d955d9;
}

The HTML part:

<canvas id="myCanvas" width="200" height="200"></canvas>
<!-- The dummy objects allowing access to the css properties -->
<div id="debug" class="logmessage-debug"></div>
<div id="info" class="logmessage-info"></div>
<div id="warn" class="logmessage-warn"></div>
<div id="error" class="logmessage-error"></div>
<div id="fatal" class="logmessage-fatal"></div>

<script type="text/javascript">
    updateCanvas();
</script>

The JavaScript part:

function updateCanvas() {
    $.ajax({
        url: "api/myWebService",
        success: function (severityLevel) {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            ctx.fillStyle = getSeverityColorFromStyle(severityLevel);
            ctx.fillRect(0, 0, c.clientWidth, c.clientHeight);
        },
        complete: function() {
            setTimeout(updateCanvas, 2000);
        }
    })
}

function getSeverityColorFromStyle(styleName) {
    // Any other way to read the css background color
    // directly instead of asking the dummy object?
    return $("#" + styleName).css("background-color");
}

So far the above way works as expected and i can get out the desired colors i like. But I'm feeling uncomfortable by adding these dummy objects just to get access to the needed css values. Exists there any direct way to retrieve these values out of the css?

Oliver
  • 43,366
  • 8
  • 94
  • 151

6 Answers6

1

You could create a function that loops through all the stylesheets/rules on your page and tries to match it

function getStyle(className) {
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
for(var x=0;x<classes.length;x++) {
    if(classes[x].selectorText==className) {
            return (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText;
        }
    }
}

See this previous post for more detail How do you read CSS rule values with JavaScript?

Community
  • 1
  • 1
JBB
  • 657
  • 5
  • 14
  • I already seen that question at SO and i simply find a little bit dumb to iterate through all this stuff on myself. I just thought there exists a *better way* instead of manual looping. – Oliver Jan 06 '14 at 12:11
1

If you know the position of the Rule or the Sheet it is in, you can easily get it via the related CSSStyleSheet, e.g.

<style id="foo">/* etc */</style>

Then

function getSeverityColorFromStyle(kwd) {
    var i, rules = document.getElementById('foo').sheet.rules;
    kwd = '.logmessage-' + kwd;
    for (i = rules.length; i--;) // find in sheet's rules
        if (rules[i].selectorText.indexOf(kwd) !== -1) // found
            return rules[i].style.backgroundColor;
    return '';
}

Accessing the style of a CSSStyleRule enables you to let the browser parse the cssText.

If you don't know the sheet, you may want to do another loop over document.styleSheets

Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • 1
    This can be further optimised if you cache the _HTMLStyleElement_ (if applicable) or the rule's indices – Paul S. Jan 06 '14 at 11:42
0
var theColor = $('.class').css('background-color');
CRABOLO
  • 8,605
  • 39
  • 41
  • 68
  • 1
    Will this work if there are no _Nodes_ in the _#document_ which match `.class`, but there is the _CSS_ rule for it? – Paul S. Jan 06 '14 at 11:22
  • I don't think so, because it doesn't exist yet as an element in the dom – Josh Beam Jan 06 '14 at 11:42
  • -1: This only works if the dummy objects are created within the html page. If you remove them you'll get an "undefined". – Oliver Jan 06 '14 at 12:15
  • @AlienArrays: That either does not work if you remove the dummy objects from the html. – Oliver Jan 06 '14 at 12:25
0

So as it seems there exists no such simple way to access a css style like accessing an existing element within the document.

At the end i decided to take the answers from Paul and JBB and (hopefully) improved them a little bit. I iterate once over all available rules within all available style sheets and push the interesting things into my own cache object. Within the getSeverityColorFromStyle() method i then try to get the matching color out of it.

var logLevelColors;

function updateCanvas() {
    if(logLevelColors == undefined)
        initializeLogLevelColors();

    $.ajax({
        url: "api/myWebService",
        success: function (severityName) {
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            ctx.fillStyle = getSeverityColorFrom(severityName);
            ctx.fillRect(0, 0, c.clientWidth, c.clientHeight);
        },
        complete: function() {
            setTimeout(updateCanvas, 2000);
        }
    })
}

function initializeLogLevelColors() {
    logLevelColors = new Object();
    var logMessageIdentifier = '.logmessage-';

    $.each(document.styleSheets, function (_, styleSheet) {
        $.each(styleSheet.rules, function (_, rule) {
            if (rule.selectorText.indexOf(logMessageIdentifier) == 0) {
                var logLevel = rule.selectorText.substring(logMessageIdentifier.length);
                var color = rule.style.backgroundColor;

                logLevelColors[logLevel] = color;
            }
        })
    })
}
function getSeverityColorFrom(severityName) {
    var undefinedColor = 'rgba(0, 0, 0, 0.00)';

    if (logLevelColors == undefined)
        return undefinedColor;

    return logLevelColors[severityName]
           || undefinedColor;
}
Oliver
  • 43,366
  • 8
  • 94
  • 151
0

How about setting the css class directly to canvas?

Something like: <canvas id="myCanvas" class="error"></canvas>, and then you could actually get the computed style of the canvas, and update the elements inside.

var canvas = document.getElementById("canvas"), styles = getComputedStyle(canvas);

//log the properties
console.log(styles.color, styles.backgroundColor);
  • Unfortunately this won't work. I simplified the example but in the real scenario i get through the web api call a list of severity levels which i have to visualize within the canvas and not only a single value. So this does not work. – Oliver Jan 08 '14 at 08:16
-1
<script type="text/javascript">
   var myText = document.getElementById("text");
   alert(myText.style.display);
   alert(myText.style.color);
   ...etc
</script>
Arthur Yakovlev
  • 8,933
  • 8
  • 32
  • 48
  • -1: There is no element (or at least this is what i like to avoid) which i could retrieve by Id. – Oliver Jan 06 '14 at 12:09