i don't like iterating though stylesheets either, but this function seems to be working.
since i don't like doing it, i took several steps to mitigate performance problems:
- all rules are cached when the builder is parsed
- @import styles don't get tested
- rules are flattened and reversed so that the first hit wins
- only elements with a defined class or id are sought
- only rules ending with these types of css selectors are tested
if a partial match is found via the class or id, the selector's finality is tested by matching the selector with the element.
the first selector- element match is assumed to be the most recent, and it's style property is returned immediately.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>css values?</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type='text/css'>
#table1, #table2 { width : 50%; }
</style>
</head>
<body>
<div id='cont'>
<table border='1' cellspacing='1' cellpadding='1' id="table1" >
<tr>
<th>aaa</th>
<th>bbb</th>
</tr>
<tr>
<td>ggg</td>
<td>vvv</td>
</tr>
</table>
</div>
<script type='text/javascript'>
var getElementDefinedStyle=(function gs(){
function R(c){return [].slice.call(c);}
var sheets=R(document.styleSheets),
sels={},
r=[];
sheets.map(function(a){
r.splice.apply(r, [r.length, 0].concat(R(a.cssRules)));
});
r.reverse();
return function getElementDefinedStyle(elm, prop){
var rx=new RegExp( "(#"+elm.id+"(,|$))|(\\."+elm.className+"(,|$))" ,"i"), out="";
r.some(function(a){
if(a.selectorText.match(rx) && document.querySelectorAll(a.selectorText)[0]==elm){
return out=a.style[prop];
}
});
return out;
};
}());//end builder wrap
window.onload= function (){
alert(
getElementDefinedStyle(
document.getElementById("table1"), "width"
)
);
};
</script>
</body>
</html>
tested firefox 3.6
if you find something better, let me know.