views:

124

answers:

1

The Problem

I have the following code:

<html>
<head>
<style id="ID_Style">
.myStyle
{
   color : #FF0000 ;
}
</style>
</head>
<body>

   <p class="myStyle">
      Hello World !
   </p>

</body>
</html>

And I want to modify the contents of <style> through JavaScript.

The Expected Solution

The first solution was to use the innerHTML property of the style element (retrieved through its id), but while it works on Firefox, it fails on Internet Explorer 7.

So, I used pure DOM methods, that is, creating an element called style, a text node with the desired content, and append the text node as a child of the style node, etc. It fails, too.

According to MSDN, the <style> element has an innerHTML property, and according to W3C, the <style> element is a HTMLStyleElement, which derives from HTMLElement, deriving from Element deriving from Node, which has the appendChild method. It seems to behave as if the content of a <style> element was readonly on Internet Explorer.

The Question

So the question is: Is there a way to modify the content of a <style> element on Internet Explorer?

While the current problem is with IE7, a cross-browser solution would be cool, if possible.

Appendix

Sources:

Style Element (MSDN): http://msdn.microsoft.com/en-us/library/ms535898.aspx

HTMLStyleElement (W3C): http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#ID-16428977

Complete Test Code

You can use this test code if you want to reproduce your problem:

<html>
<head>
<style id="ID_Style">
.myStyle
{
   color : #FF0000 ;
}
</style>
<script>
function replaceStyleViaDOM(p_strContent)
{
   var oOld = document.getElementById("ID_Style") ;
   var oParent = oOld.parentNode ;
   oParent.removeChild(oOld) ;

   var oNew = document.createElement("style") ;
   oParent.appendChild(oNew) ;

   oNew.setAttribute("id", "ID_Style") ;
   var oText = document.createTextNode(p_strContent) ;
   oNew.appendChild(oText) ;
}

function replaceStyleViaInnerHTML(p_strContent)
{
   document.getElementById("ID_Style").innerHTML = p_strContent ;
}
</script>
<script>
function setRedViaDOM()
{
   replaceStyleViaDOM("\n.myStyle { color : #FF0000 ; }\n")
}

function setRedViaInnerHTML()
{
   replaceStyleViaInnerHTML("\n.myStyle { color : #FF0000 ; }\n")
}

function setBlueViaDOM()
{
   replaceStyleViaDOM("\n.myStyle { color : #0000FF ; }\n")
}

function setBlueViaInnerHTML()
{
   replaceStyleViaInnerHTML("\n.myStyle { color : #0000FF ; }\n")
}

function alertStyle()
{
   alert("*******************\n" + document.getElementById("ID_Style").innerHTML + "\n*******************") ;
}
</script>
</head>
<body>

   <div>
      <button type="button" onclick="alertStyle()">alert Style</button>
      <br />
      <button type="button" onclick="setRedViaDOM()">set Red via DOM</button>
      <button type="button" onclick="setRedViaDOM()">set Red via InnerHTML</button>
      <br />
      <button type="button" onclick="setBlueViaDOM()">set Blue via DOM</button>
      <button type="button" onclick="setBlueViaInnerHTML()">set Blue via InnerHTML</button>
   </div>

   <p class="myStyle">
      Hello World !
   </p>

</body>
</html>

Thanks !

Edit

Note that moving the <style> element from the <head> into the <body> doesn't change the problem.

+1  A: 

Here is a handy page that explains the intricacies of manipulating stylesheets with JS. It also goes into the differences between how it's done for IE v.s. standards-based browsers.

Totally Pwn CSS with Javascript

Diodeus
@Diodeus: Looking at the code in the page you mentionned, I see I can resolve my problem with additional code on my page. Not as easy as I would have wanted, still, it is a solution (and perhaps, the unique solution). I'll test it tomorrow.
paercebal
Yeah, there are a few things in JavaScript that are still ugly, this being one of them. Managing text cursor positions is another.
Diodeus
+1, by the way.
paercebal