Reputation: 523
I have this very simple HTML page, and I'm trying to get the CSSRules of #poulet, but when I'm accessing the documents.styleSheets[0].cssRules I get this error in Chrome v5.0.375.55:
Uncaught TypeError: Cannot read property 'length' of null
Here is what my code looks like:
HTML FILE
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/test.css" type="text/css" />
<script type="text/javascript" src="js/test.js"></script>
<title>Mozilla</title>
<script>
window.onload = function(){
var test = findKeyframesRule('poulet');
alert(test);
}
</script>
</head>
<body>
<div id="poulet">
allo
</div>
</body>
</html>
JS FILE
function findKeyframesRule(rule)
{
var ss = document.styleSheets;
for (var i = 0; i < ss.length; ++i)
{
for (var j = 0; j < ss[i].cssRules.length; ++j)
{
if (ss[i].cssRules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && ss[i].cssRules[j].name == rule)
return ss[i].cssRules[j];
}
}
return null;
}
CSS FILE
html, body {
background: #cccccc;
}
#poulet{
border: 10px solid pink;
}
The files can be found here. I really need help on this one, please!!! D:
Upvotes: 4
Views: 11533
Reputation: 104820
This method returns an array of rules that contain a given selector-
to work in correctly IE, the selector test has to be case insensitive.
Chrome 5 will work with either rules or cssRules, by the way.
function findRule(rule){
var ss= document.styleSheets, L= ss.length, A= [], R, RL, ru;
var rx= RegExp('\\b'+rule+'\\b','i');
for(var i= 0; i < L; ++i){
R= ss[i].cssRules || ss[i].rules,
RL= R.length;
while(RL){
ru= R[--RL];
if(rx.test(ru.selectorText)){
A.unshift(ru.selectorText+'{'+ru.style.cssText+'}');
}
}
}
return A;
}
alert(findRule('body').join('\n\n'))
Note-may be of use to you-
If I run this in a directory on my c-drive I can't read any styleSheet's length or rules unless they are in the same directory as the page.
It runs fine when served via http- from localhost or the internet.
Upvotes: 2
Reputation: 21763
I found these errors in your script:
You're testing for type being equal to window.CSSRule.WEBKIT_KEYFRAMES_RULE
. That property has a value of 8, whereas the desired object has a type of 1. A quick look in the CSSRule
object reveals that you probably want to compare with window.CSSRule.STYLE_RULE
.
I couldn't find a property name
, but in the end found a property selectorText
containing #poulet
.
After corrections the script reads:
function findKeyframesRule(rule)
{
var ss = document.styleSheets;
for (var i = 0; i < ss.length; ++i)
{
for (var j = 0; j < ss[i].cssRules.length; ++j)
{
if (ss[i].cssRules[j].type == window.CSSRule.STYLE_RULE && ss[i].cssRules[j].selectorText == '#'+rule)
return ss[i].cssRules[j];
}
}
return null;
}
But beware of the problem I mentioned in a comment: this only works when protocol != "file:"
,
Upvotes: 3
Reputation: 19368
Chrome uses the rules[]
array like IE.
document.styleSheets[0].rules.length
So modify your loop:
for (var i = 0; i < ss.length; ++i)
{
var rules = ss[i].cssRules;
if (!rules)
rules = ss[i].rules;
for (var j = 0; j < rules.length; ++j)
{
if (rules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && rules[j].name == rule)
return rules[j];
}
}
Upvotes: 0