I am currently trying to make my own polyfill that will allow older browsers such as Internet Explorer the ability to read and execute media queries using traditional css selectors. The process flow goes something like this:
- Iterate through each stylesheet found within document
- Run through each style rule in stylesheet searching for media queries
- Define what device size we are targeting then apply appropriate "id"
- Dynamically add css line with selector to existing stylesheet
The idea is that the polyfill will search for media queries then apply a parent "id" to the body corresponding to the device size, for instance:
#tablet .wrap { ... }
#mobile .wrap { ... }
#desktop .wrap { ... }
Here is what the javascript looks like so far:
var styleSheets = document.styleSheets;
var debug = false;
var ruleParts = mediaPart = rules = compiledSel = className = '';
var dimS = dimB = 0;
var idList = Array('smallMobile','mobile','tablet','smallDesktop','desktop');
// run through each stylesheet
for( i = 0; i < styleSheets.length; i++ ) {
// If uncommented will show each stylesheets rules contained therein
if( debug ) {
console.log( styleSheets[i].cssRules );
}
// run through each rule declaration
for( a = 0; a < styleSheets[i].rules.length; a++ ) {
if( styleSheets[i].rules[a].type == 4 ) {
mediaPart = styleSheets[i].rules[a].media[0].split(' and ');
dimS = parseInt( mediaPart[0].replace(/[():A-Za-z$-]/g, "") );
dimB = parseInt( mediaPart[1].replace(/[():A-Za-z$-]/g, "") );
if( dimS > 0 && dimB < 418 ) {
className = idList[0];
} else if( dimS > 419 && dimB < 767 ) {
className = idList[1];
} else if( dimS > 768 && dimB < 1024 ) {
className = idList[2];
} else if( dimS > 1025 && dimB < 1201 ) {
className = idList[3];
} else {
className = idList[4];
}
if( styleSheets[i].rules[a].cssRules.length > 1 ) {
for( b = 0; b < styleSheets[i].rules[a].cssRules.length; b++ ) {
ruleParts = styleSheets[i].rules[a].cssRules[b].cssText.split('{');
rules = ruleParts[1].split('}');
addCSSRule( styleSheets[i], '#'+ className +' '+ ruleParts[0], rules[0], 1 );
/*
* Investigate why the .insertRule() and addRule() are failing specifically what is causing them to break
*
*/
}
} else {
}
}
}
}
function addCSSRule(sheet, selector, rules, index) {
if(sheet.insertRule) {
sheet.insertRule(selector + "{" + rules + "}", index);
} else {
sheet.addRule(selector, rules, index);
}
}
Right now everything is working the way I want, even adding the css rule to the style sheet however I get this error and I'm not totally sure at what point:
Uncaught TypeError: Cannot read property 'length' of undefined
If I remove the function call to this line, I don't get the error:
addCSSRule( styleSheets[i], '#'+ className +' '+ ruleParts[0], rules[0], 1 );
So I'm not sure what is happening during the function call and the reading of the .length
My html looks something like this:
<!DOCTYPE html>
<head>
<title>Style Manipulation VIA Javascript</title>
<link rel="stylesheet" href="css/test.css" />
<link rel="stylesheet" href="css/typo.css" />
</head>
<body>
<div class="wrap">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</div>
Overall I need to figure out why the property length can't be read and what in the addCSSRule
function call is causing the error.