DaE
DaE

Reputation: 189

rule.style is undefined when processing document.styleSheets

Please bare in mind that I am still learning JavaScript so be kind please.

I have the following code which searches a webpage for any CSS containing HTTP urls. However, there is one variable "v" which can sometimes be undefined. Error "rule.style is undefined"

How can I resolve this undefined response? I have tried to use conditions but with no luck.

var seachHttp = function () {
    var cssSheets = document.styleSheets, // Loaded CSS Sheets
        i =0, il = cssSheets.length, // Counter and limit for sheets
        j, jl, rules, rule, // Counter and vars for Rules inside a Sheet
        stylesToSearch = [ // Properties to Seach HTTP ON
            'background',
            'background-image',
        ],
        k, kl=stylesToSearch.length, // Counter for properties
        s, // Current Property
        v;  // Current Value
    for(;i<il;i++) { // Loop Sheets
        rules = cssSheets[i].rules || cssSheets[i].cssRules;
        for(j=0,jl=rules.length;j<jl;j++) { // Loop Rules
            rule = rules[j];
            for(k=0;k<kl;k++){ // Loop Styles
                s = stylesToSearch[k]; 
                v = rule.style[s]; // Get Value from Current Style
                if ( typeof v !== undefined && v.toString().toLowerCase().indexOf("http") > -1 ) { // Seach for HTTP Content
                    alert("Found HTTP at " + rule.selectorText + " " + s + " = " + rule.style[s]);
                    return true;

                }
            }
        }
    }
    return false;
}

I call this function using:

var cssresult = seachHttp();
if (cssresult == true && cssresult !== undefined) {
//code here
}

Upvotes: 2

Views: 807

Answers (1)

Nickolay
Nickolay

Reputation: 32073

Since the error says "rule.style is undefined", your error probably happens on the v = rule.style[s] line because you can't look up properties on non-objects (undefined[s]).

When rule.style is undefined? When a rule object doesn't have a style property.

What kind of object is rule? It's a CSSRule. (You could've looked up document.styleSheets on MDN to figure it out yourself or just put a console.log(rule) before the error, or learn to use your browser's devtools debugger).

As you can see from the MDN page, a generic CSSRule doesn't have a style property, only a certain type - CSSStyleRule - does. That's because apart from style rules (i.e. selector { background: ... }), a CSS stylesheet can contain other constructs, e.g. @media screen { ... }, which itself obviously doesn't have any properties (like background).

What you should do depends on what your goal is:

  • The simplest solution would be to limit this code to CSSStyleRules and check if (rule instanceof CSSStyleRule) or rule.type == CSSRule.STYLE_RULE (I'm assuming a standards-compliant browser here of course).
  • If you wished, you could process the other types of rules, e.g. recurse into the @media rules to check the styles defined inside them. This is definitely out of scope for this answer, though.

Upvotes: 1

Related Questions