Final cross browser way to dynamically insert style elements into the DOM - javascript

Although inserting style nodes into the DOM sounds rather trivial, I have found many contradictory ways to do so. So I decided to look it up on stackoverflow and it appears that many posts offer methodologies that do what I need, however they do not necessarily agree with each other.
I came across the following javascript methods:
Returns a style element, and apparently does not have the "styleSheet" property in older browsers.
document.createElement("style")
Returns a styleSheet object, although I do not know how you would subsequently access the style element (which you will need to insert into the DOM).
document.createStyleElement()
The first three methods below work on styleSheets, others are "hacks" that work directly on the style nodes.
styleSheet.cssText
styleSheet.addRule
styleSheet.insertRule
style.createTextNode
style.innerHTML
I also had a hard time finding the correct syntax to use on (at least) the first three styleSheet methods. E.g. whether or not it is mandatory to include the curly braces and semicolons.
Also, these properties are used for accessing a styleSheet in various browsers:
document.styleSheets[index]
element.styleSheet
element.sheet
What would be the correct bundle of methods to use for a cross browser approach on inserting style elements? This should cover older browsers like IE6, subselectors (such as :visited) and !important statements.

Processed from this question:
var css = 'h1 { background: red; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet)
style.styleSheet.cssText = css;
else
style.appendChild(document.createTextNode(css));
head.appendChild(style);
It says it was tested in IE 7-9, Firefox, Opera, and Chrome, so it's pretty compatible.
And here are two links that might help:
Dynamic style - manipulating CSS with JavaScript - W3C Wiki
W3C DOM Compatibility - CSS

My proposal:
var elem = document.createElement('style');
elem.innerHTML = 'body { background: green }';
document.body.appendChild(elem);
Live demo: http://jsfiddle.net/simevidas/bhX86/
I'm looking into how to make this work in IE8.

You mean something like this? This should be cross-browser.
HTML
<div id="target">text</div>
Javascript
function injectStyle(data, attributes, inBody) {
attributes = attributes || {};
inBody = inBody || false;
var inject = document.createElement("style"),
i;
inject.type = "text/css";
for (i in attributes) {
if (attributes.hasOwnProperty(i)) {
inject[i] = attributes[i];
}
}
inject.appendChild(document.createTextNode(data));
if (inBody) {
return document.body.appendChild(inject);
}
return (document.head || document.getElementsByTagName("head")[0] || document.documentElement).appendChild(inject);
}
injectStyle("#target { border-style: solid; border-width: 5px; }", {
id: "injectedStyle"
});
on jsfiddle

Related

Not display ::ms-clear pseudo element using JavaScript

I want to disable/remove/not display the ::ms-clear button that is appearing in input fields in IE. How can I do the following
input[type=text]::-ms-clear { display: none; }
using JavaScript? It is sufficient for me to do this on each HTMLInputElement if that is easier.
(I wish not to use any external libraries such as jQuery)
It seems that pseudo-elements are readonly? I am trying to do
window.getComputedStyle(this.inputTextElement, "::ms-clear").setProperty("display", "none");
but I get exception NoModificationAllowedError.
The closest working thing to set this in JavaScript seems to be doing
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '::-ms-clear{display:none};';
document.getElementsByTagName('head')[0].appendChild(style);

Can I programmatically traverse a CSS stylesheet?

jQuery provides a nice, neat way to traverse the DOM...what I'm looking for is a way to traverse a stylesheet, getting and setting attributes for the defined styles.
Example Stylesheet
div {
background: #FF0000;
display: block;
}
.style {
color: #00AA00;
font-family: Verdana;
}
html body > nav.menu {
list-style: none;
}
Now imagine the following code is like jQuery for CSS...
Getting values from the CSS
$("div").attr("background");
//returns #FF0000;
$(".style").attr("color");
// returns #00AA00;
$("html body > nav.menu").attr("color");
// returns undefined;
Setting values in the CSS
$("div").attr("background", "#0000FF");
$(".style").attr("color", "#CDFF4E");
$("html body > nav.menu").attr("color", "#FFFFFF");
Fairly certain this is not possible...but just a wild stab in the dark!
I think you can, but the interface is more obtuse than you probably want.
document.styleSheets returns a StyleSheetList object that seems to behave in an array like way.
So document.styleSheets[0] returns a CSSStyleSheet object. Look to have lots of ways to analyze it's content. And each CSSStyleSheet has a cssRules property which returns a CSSRuleList.
And you can traverse the docs on the various types return by the DOM api from there yourself: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet
I just found a way to look through all of your style sheets, using jquery initially:
I have three stylesheets on my page, so first, I must identify the one I need to manipulate and I gave it an id:
<style id="localRules">...</style>
Then, I use jQuery to initially find the id'd stylesheet I'm planning to change:
var sheetToChange = "localRules";
var sheets = $(document.styleSheets);
// loop through all the stylesheets
for (var thisSheet=0;thisSheet<sheets.length;thisSheet++){
// find the right stylesheet to work on
if(sheets[thisSheet].ownerNode.id == sheetToChange ){
// cross browser referencing of css rules:
var ruleSet = sheets[thisSheet].cssRules || sheets[thisSheet].rules;
for (var thisRule=0;thisRule<ruleSet.length;thisRule++){
// traverse in that style sheet for the rule you want to change, in this case, body:
if(ruleSet[thisRule].selectorText == "body"){
ruleSet[thisRule].style.cursor = "pointer";
}
}
break;
}
}
Hope this is helpful...it worked for me, but took a while to figure it out, especially because ownerNode is something I've never heard of before.

How to dynamically set and modify CSS in JavaScript?

I have some JavaScript code that creates some div elements and it sets their CSS properties.
Because I would like to decouple CSS logic from my JavaScript code and because CSS is easier to read in its own .css file, I would like to set the CSS className of my element and then dynamically inject some values into the defined CSS property.
Here is what I would like to do :
style.css:
.myClass {
width: $insertedFromJS
}
script.js:
var myElement = document.createElement("div");
myElement.className = "myClass";
I want to do something like this but at that point myElement.style.width is empty
myElement.style.width.replaceAll("$insertedFromJS", "400px");
I think my problem here is that after the call to myElement.className = "myClass", the CSS is not yet applied.
If I understand your question properly, it sounds like you're trying to set placeholder text in your css file, and then use javascript to parse out the text with the css value you want to set for that class. You can't do that in the way you're trying to do it. In order to do that, you'd have to grab the content of the CSS file out of the dom, manipulate the text, and then save it back to the DOM. But that's a really overly-complicated way to go about doing something that...
myElement.style.width = "400px";
...can do for you in a couple of seconds. I know it doesn't really address the issue of decoupling css from js, but there's not really a whole lot you can do about that. You're trying to set css dynamically, after all.
Depending on what you're trying to accomplish, you might want to try defining multiple classes and just changing the className property in your js.
Setting the style, might be accomplished defining the inner-page style declaration.
Here is what i mean
var style = document.createElement('style');
style.type = 'text/css';
style.cssText = '.cssClass { color: #F00; }';
document.getElementsByTagName('head')[0].appendChild(style);
document.getElementById('someElementId').className = 'cssClass';
However the part of modifying it can be a lot of tricky than you think. Some regex solutions might do a good job. But here is another way, I found.
if (!document.styleSheets) return;
var csses = new Array();
if (document.styleSheets[0].cssRules) // Standards Compliant {
csses = document.styleSheets[0].cssRules;
}
else {
csses = document.styleSheets[0].rules; // IE
}
for (i=0;i<csses.length;i++) {
if ((csses[i].selectorText.toLowerCase()=='.cssClass') || (thecss[i].selectorText.toLowerCase()=='.borders'))
{
thecss[i].style.cssText="color:#000";
}
}
could you use jQuery on this? You could use
$(".class").css("property", val); /* or use the .width property */
There is a jQuery plugin called jQuery Rule,
http://flesler.blogspot.com/2007/11/jqueryrule.html
I tried it to dynamically set some div sizes of a board game. It works in FireFox, not in Chrome. I didn't try IE9.

How do you change the background color of an <input> element with javascript

I have a <input> element that I want to change the background color on. The code I am currently using is this (but it is not working):
var allBlanksLoc = document.getElementById('text');
var allBlanks = allBlanksLoc.getElementsByTagName('input');
for(i=0; i<allBlanks.length; i++) {
var currentBlank = allBlanks[i];
var wordNum = blanks[i];
var blankWord = text[wordNum];
var usrAnswer = currentBlank.value;
if (usrAnswer != blankWord) {
currentBlank.style.backgroundColor = "red";
}
}
The third to last line being the most important
Update:
I fixed the camelCase on it but it still does not work. Any ideas of bugs there?
The full code is here: http://jsbin.com/imolo3/edit
Case is important. What you need is
document.getElementById('test').style.backgroundColor='red';
However
it would be better to use a css rule and use javascript only to add the class to the element.
CSS Rule
input.invalid {
background-color: red;
}
Javascript
element.className = 'invalid';
It should be backgroundColor - notice the capital C, JavaScript is case-sensitive.
Are you sure that this script is running at the right time? If it runs before the page is fully formed, the appropriate elements might not be present.
So not to repeat the solutions other users gave.
I personally use JQuery (and it's where any javascripter ends, overall for browser compatibility issues), and it would:
$(currentBlank).css("background-color","red");

Adding #import statement in a dynamic stylesheet for IE7+

I have a problem with adding a dynamic style element with #import statements for IE. Try this:
var string = '#import url(test.css)';
var style = document.createElement('style');
if (style.styleSheet) { // IE
style.styleSheet.cssText = string;
} else {
var cssText = document.createTextNode(string);
style.appendChild(cssText);
}
document.getElementsByTagName('head')[0].appendChild(style);
This works for FF/Chrome but not IE. It seems to recognize style.styleSheets.imports, but it will not apply the imported stylesheet. Is this a bug or limitation?
Many older browsers can't process varying forms of the #import directive, this can be used to hide css from them. Check http://www.w3development.de/css/hide_css_from_browsers/import/ for details.
The #import directives must come first in a style sheet, or else they'll be ignored. however IE doesn't ignore misplaced #import directives.
Edit: See the addImport method for injecting style sheets in IE.

Categories

Resources