To add a rule or delete one you want to know a rule’s index. You want to dynamically determine the numeric index of a rule in cross-browser
Let’s code a helper function findIndex()
.
It returns undefined because findIndex()
ought to return a number. Those are stored on the stack, and undefined conveys no value on the stack.
function findIndex(element, selector) { var sheet = element.sheet || element.styleSheet; var rules = sheet.cssRules || sheet.rules; selector = selector.toLowerCase() for (var i = rules.length - 1; i > -1; i--) { if (rules[i].selectorText && rules[i].selectorText.toLowerCase() === selector) { return i; } } }
Find the numeric index of the rule with the "a#adidas"
selector with findIndex()
findIndex(document.getElementById("spriteStyles"), "a#adidas");
With the numeric index of a rule, we can explore how to insert a rule into a style sheet.
Lets code the helper function insertRule()
.
This function has four parameters:
Parameter | Description |
---|---|
element | will be a <link> or <style> Element node. |
selector | will be the text of the selector for the new rule, in other words, a string like "div#running li" . |
declarations | will be the text of the declaration block, minus the curly braces, such as a string like "top:135px; background-position:0 -81px" . |
index | contains the text of the selector for the rule you want to insert the new rule before. So, that’s the selector string we will pass to findIndex(), which will then return a numeric index, or undefined. |
function insertRule(element, selector, declarations, index) { }
Now let’s move on to the body of our helper function.
So far we have this:
function insertRule(element, selector, declarations, index) { var sheet = element.sheet || element.styleSheet; var rules = sheet.cssRules || sheet.rules; if (typeof index === "string") { index = findIndex(element, index); } if (typeof index !== "number") { index = rules.length; } }
Now sheet will contain either a DOM method named insertRule()
or an Internet Explorer method named addRule()
.
When Firefox, Safari, or Opera is running our function, insertRule()
will be defined. This method takes two parameters:
For Internet Explorer to run. Its method, addRule()
, takes three parameters:
The text for the selector, the text for the declarations, and the numeric index for where to insert the rule.
Simply pass in the values of selector, declarations, and index.
function insertRule(element, selector, declarations, index) { var sheet = element.sheet || element.styleSheet; var rules = sheet.cssRules || sheet.rules; if (typeof index === "string") { index = findIndex(element, index); } if (typeof index !== "number") { index = rules.length; } if (sheet.insertRule) { sheet.insertRule(selector + "{" + declarations + "}", index); } else if (sheet.addRule) { sheet.addRule(selector, declarations, index); } }
insertRule(document.getElementById("spriteStyles"), "ul.blue a", "background-image:url(images/fuchsia.gif)", "ul.fuchsia a");
insertRule(document.getElementById("spriteStyles"), "ul.blue a", "background-image:url(images/green.gif)");
Let’s code a helper function to delete a rule from a style sheet. Similar to insertRule()
we will have Firefox, Safari, and Opera invoke the DOM method, deleteRule()
, and Internet Explorer will invoke its proprietary one, removeRule()
.
The helper functions insertRule()
and deleteRule()
are methods of window.The function has two named arguments:
<link>
or <style>
Element node.The DOM and Internet Explorer functions for deleting a rule are methods of a CSSStyleSheet object, we need to save a reference to the one containing the rule to delete. Put that in a local variable named sheet. Then save the return value of passing element and selector to findIndex()
to another local variable named index. If findIndex()
return undefined instead of a number, we cannot delete a rule, So, write an if statement to abort deleteRule()
in the event we have no numeric index to work with.
Thus far we have this:
function deleteRule(element, selector) { var sheet = element.sheet || element.styleSheet; var index = findIndex(element, selector); if (typeof index !== "number") { return; } }
Both the DOM and Internet Explorer methods work with one parameter, the numeric index of the rule to delete.
function deleteRule(element, selector) { var sheet = element.sheet || element.styleSheet; var index = findIndex(element, selector); if (typeof index !== "number") { return; } if (sheet.deleteRule) { sheet.deleteRule(index); } else if (sheet.removeRule) { sheet.removeRule(index); } }
We delete a rule just added with insertRule()
. Those both have a selector of "ul.blue a". We pass "ul.blue a"
to deleteRule()
.
deleteRule(document.getElementById("spriteStyles"), "ul.blue a");