Using Javascript To Dynamically Add Styles To Stylesheet But I Get A "cannot Read Property 'length' Of Undefined" Error
Solution 1:
There are significant differences between the IE and W3C implementations of the styleSheets object, hopefully the following is explanatory enough to help:
function getStyleRules() {
var rule, rules;
var sheet, sheets = document.styleSheets;
var ruleCssText = ['Rules:','',]
for (var i=0, iLen=sheets.length; i<iLen; i++) {
sheet = sheets[i];
// Get the rules using://// W3C model IE model
rules = sheet.cssRules || sheet.rules;
for (var j=0, jLen=rules.length; j<jLen; j++) {
rule = rules[j];
// The selector is available here in both models,// but uppercase in IE so set to lower case
alert('Selector: ' + rule.selectorText.toLowerCase());
// Getting the actual rule text// W3C model - selector and ruleif (rule.cssText) {
ruleCssText.push(rule.cssText);
// IE model - rule only, doesn't include selector
} elseif (rule.style) {
ruleCssText.push(rule.style.cssText.toLowerCase());
}
}
alert(ruleCssText.join('\n'));
}
}
There is documentation on MSDN of the IE model, but I'm not sure if it still covers older IE or only the newer versions which may well use both models: styleSheet object, rule object
There is some Opera documentation here: Dynamic style - manipulating CSS with JavaScript
and also some information here: The styleSheet object, The CSS Rule object.
As with all web resources, take it with a serious amount of skepticism, look for other sources and test, test, test in as many browsers (especially older ones) as you can.
Running your code:
> TypeError: styleSheets[i].rules is undefined
>
> for( a = 0; a < styleSheets[i].rules.length; a++ ) {
Here you are mixing the IE (rules) and W3C (cssRules) models. Better to just get the rules object once: -
var sheetRules = styleSheets[i].rules || styleSheets[i].cssRules;
for( a = 0; a < sheetRules.length; a++ ) {
Then you have:
if ( sheetRules[a].type == 4 ) {
but the IE model doesn't implement a type property for the rules object (even though the MSDN documentation says it does, that's for the W3C model implemented by IE 9 and later).
Then:
> mediaPart = sheetRules[a].media[0].split(' and ');
Note that media is a property of the sheet, not of a rule, so:
// Perhaps mediaParts (plural)?
mediaPart = styleSheets[i].media;
And just to be nasty, the IE model has a media property with a type of string, but it's empty. You can get the text of it using:
styleSheets[0].cssText.replace(/\s+/g,' ').match(/@media.+}[^{]+}/)
.
> // TypeError: mediaPart[1] is undefined
> dimB = parseInt( mediaPart[1].replace(/[():A-Za-z$-]/g, "") );
Here you seem to be expecting "and" to be in the rule. You haven't provided an example of your rules, but if they are like:
@media screen, print { ... }
then media is a list of the media rules: media[0]
is screen and media[1]
is print, so you want to iterate over the media rules.
Anyhow, that's enough for now.
Post a Comment for "Using Javascript To Dynamically Add Styles To Stylesheet But I Get A "cannot Read Property 'length' Of Undefined" Error"