ASM wrote:
pa***********@l ibero.it a crit :
>>
The purpose is simply that I want to add some css/html
dinamically from javascript. It's kind of optional code that
I need to add "onload" only under some circumstances.
Have a go with this class. Tested on IE, Moz and Opera. YMMV.
/**
An object which encapsulates a dynamically created, modifiable stylesheet.
*/
function CSSStyleSheet()
{
/**
* The array of rules for this stylesheet.
* @private
*/
this.rules = [];
/**
* An associative array, keyed by the selector text containing the rule index number for
* the rule for that selector text.
* @private
*/
this.ruleIndex = [];
if (document.creat eStyleSheet)
{
this.sheet = document.create StyleSheet();
}
else
{
this.styleEleme nt = document.create Element("style" );
document.getEle mentsByTagName( "head")[0].appendChild(th is.styleElement );
this.sheet = this.styleEleme nt.styleSheet ? this.styleEleme nt.styleSheet : this.styleEleme nt.sheet;
}
}
/**
Create a style rule in the stylesheet.
@param selectorText The CSS selector text.
@param ruleText The style specification with or without braces.
*/
CSSStyleSheet.p rototype.addRul e = function(select orText, ruleText)
{
var result;
// Opera, and other browsers with no DOM stylesheet support
if (!this.sheet)
{
// Remove braces.
ruleText = ruleText.replac e(/^\{?([^\}])/, "$1");
// If it exists, modify it.
if (!this.ruleInde x[selectorText])
this.ruleIndex[selectorText] = this.rules.leng th;
this.rules[this.ruleIndex[selectorText]] = ruleText;
// Build the innerHTML of the <styleelement from our rules.
var cssText = "";
for (var sel in this.ruleIndex)
cssText = sel + " {" + this.rules[this.ruleIndex[sel]] + "}";
this.styleEleme nt.innerHTML = cssText;
}
// IE.
// Each rule object has a style property which contains the style attributes.
else if (this.sheet.add Rule)
{
// addRule() requires no braces
ruleText = ruleText.replac e(/^\{?([^\}])/, "$1");
var r = this.sheet.rule s.length;
this.sheet.addR ule(selectorTex t, ruleText);
result = this.sheet.rule s[r];
this.ruleIndex[selectorText] = r;
if (this.rules.len gth == 0)
this.rules = this.sheet.rule s;
}
// DOM standard. Result object contains looks like {cssText:select orText + " " + ruleText}
// cssText property is readonly. deleteRule(rule Index} must be used to remove.
else if (this.sheet.ins ertRule)
{
// insertRule() requires braces
if (!/^\{[^\}]*\}$/.test(ruleText) )
ruleText = "{" + ruleText + "}";
var r = this.sheet.cssR ules.length;
this.sheet.inse rtRule(selector Text + " " + ruleText, r);
result = this.sheet.cssR ules[r];
this.ruleIndex[selectorText] = r;
if (this.rules.len gth == 0)
this.rules = this.sheet.cssR ules;
}
else
{
alert("Cannot create rule");
}
return result;
}
/**
* Change a style property in a rule.
* @param selectorText The identifier of the rule to change
* @param property The name of the style property to change
* @param value The new value of the style property.
*/
CSSStyleSheet.p rototype.change Rule = function(select orText, property, value)
{
var index = this.ruleIndex[selectorText];
// If the rule is not present, create it.
if (typeof index == "undefined" )
{
this.addRule(se lectorText, property + ":" + value);
}
// Opera, and other browsers with no DOM stylesheet support
if (!this.sheet)
{
var cssText = this.rules[index];
if (cssText)
{
var propSearch = new RegExp("^(.*" + property + "\\s*\:\\s* )([^;]*)(.*)$");
var ruleText = propSearch.exec (cssText);
// If the value was in the old rule...
if (ruleText)
{
// And it was different...
if (ruleText[4] != value)
{
this.rules[index] = ruleText[1] + value + ruleText[3];
}
}
else
{
this.rules[index] = cssText + "; " + property + ": " + value + ";";
}
// Rebuild the innerHTML of the <styleelement from our rules.
cssText = "";
for (var sel in this.ruleIndex)
cssText = sel + " {" + this.rules[this.ruleIndex[sel]] + "}";
this.styleEleme nt.innerHTML = cssText;
}
var cssText = "";
var cssText = "";
for (var sel in this.ruleIndex)
cssText = sel + " {" + this.rules[this.ruleIndex[sel]] + "}";
}
// rules contain a style object - easy
else if (this.rules[index].style)
{
// Make the property camelCase
var m = /^([^-]*)-([a-z])(.*)$/.exec(property) ;
while (m)
{
property = m[1] + m[2].toUpperCase() + m[3];
m = /^([^-]*)-([a-z])(.*)$/.exec(property) ;
}
// Use the style property of the rule.
this.rules[index].style[property] = value;
}
// DOM standard. We must parse the rule, delete, and create a new one.
else if (this.sheet.ins ertRule)
{
var oldRule = this.rules[index];
if (oldRule)
{
var cssText = oldRule.cssText ;
var propSearch = new RegExp("^[^\\{]*(\\{.*" + property + "\\s*\\:\\s *)([^};]*)([^}]*})");
var ruleText = propSearch.exec (cssText);
// If the value was in the old rule...
if (ruleText)
{
// And it was different...
if (ruleText[4] != value)
{
cssText = ruleText[1] + value + ruleText[3];
this.sheet.dele teRule(index);
this.sheet.inse rtRule(selector Text + " " + cssText, index);
}
}
else
{
var propSearch = new RegExp("\\{([^}]*)}");
ruleText = propSearch.exec (cssText);
cssText = "{ " + ruleText[1] + "; " + property + ": " + value + " }";
this.sheet.dele teRule(index);
this.sheet.inse rtRule(selector Text + " " + cssText, index);
}
}
}
}
CSSStyleSheet.p rototype.getRul eProperty = function(select orText, property)
{
var index = this.ruleIndex[selectorText];
// If the rule is not present, create it.
if (typeof index == "undefined" )
{
return;
}
// Opera, and other browsers with no DOM stylesheet support
if (!this.sheet)
{
var cssText = this.rules[index];
if (cssText)
{
var propSearch = new RegExp("^.*" + property + "\s*\:\s*([^;]*)");
var ruleText = propSearch.exec (cssText);
// If the value was in the old rule...
if (ruleText)
{
return ruleText[1];
}
}
}
// rules contain a style object - easy...
else if (this.rules[index].style)
{
// Make the property camelCase
var m = /^([^-]*)-([a-z])(.*)$/.exec(property) ;
while (m)
{
property = m[1] + m[2].toUpperCase() + m[3];
m = /^([^-]*)-([a-z])(.*)$/.exec(property) ;
}
var style = this.rules[index].style;
return style[property];
}
// DOM: We must parse the rule cssText.
else if (this.sheet.ins ertRule)
{
var oldRule = this.rules[index];
if (oldRule)
{
cssText = oldRule.cssText ;
var propSearch = new RegExp("^.*" + property + "\\s*\\:\\s *([^};]*)");
var ruleText = propSearch.exec (cssText);
// If the value was in the old rule...
if (ruleText)
{
return ruleText[1];
}
}
}
}