开发者

controlling css with javascript works with Mozilla & Chrome however not with IE

Im having problems with this function applying css(using a text variable) working with Internet Explorer but it works in Firefox & Chrome.

the code:

/*! addCssStyle() applies the text value $CssText$ to the the specified document
$Doc$ e.g. an IFrame; or if none specified, default to the current 开发者_如何学编程document,
*/function addCssStyle(CssText, Doc){

//Secure $Head$ for the current $Doc$
    Doc = Doc||document;    var head = Doc.getElementsByTagName('head')[0];
    if(!head || head == null){
        head = Doc.createElement('div');    Doc.body.appendChild(head);
    } if(!head || head == null){return false;}

//createElement('style')
    var PendingStyle = Doc.createElement('style');
//  if (is_gecko){PendingStyle.href = 'FireFox.css';}//???needeed???
    PendingStyle.type = 'text/css';
    PendingStyle.rel = 'stylesheet';
//  PendingStyle.media = 'screen';//???needeed???
    PendingStyle.innerHTML = CssText;
    head.appendChild(PendingStyle);

}/*___________________________________________________________________________*/

the use of the function:

var NewSyleText = //The page styling
"h1, h2, h3, h4, h5 {font-family: 'Verdana','Helvetica',sans-serif; font-style: normal; font-weight:normal;}" +
"body, b {background: #fbfbfb; font-style: normal; font-family: 'Cochin','GaramondNo8','Garamond','Big Caslon','Georgia','Times',serif;font-size: 11pt;}" +
"p { margin: 0pt; text-indent:2.5em;  margin-top: 0.3em; }" +
"a {    text-decoration: none; color: Navy; background: none;}" +
"a:visited {    color: #500050;}" +
"a:active { color: #faa700;}" +
"a:hover {  text-decoration: underline;}";
addCssStyle(NewSyleText);//inserts the page styling


var style = document.createElement('style');

Adding new stylesheets and scripts by creating elements using DOM methods is something that has always been dicey cross-browser. This won't work in IE or WebKit.

style.rel = 'stylesheet';
style.href = 'FireFox.css';

There's no such properties on an HTMLStyleElement. <style> contains inline code. For external stylesheets, use a <link>. By luck, it happens this does work:

var link= document.createElement('link');
link.rel= 'stylesheet';
link.href= 'something.css';
head.appendChild(link);

But doesn't give you a convenient way to insert rules from script.

You can also add new rules to an existing stylesheet (eg. an empty style in the <head>) by using the document.styleSheets interface. Unfortunately, IE's interface doesn't quite match the standard here so you need code branching:

var style= document.styleSheets[0];
if ('insertRule' in style)
    style.insertRule('p { margin: 0; }', 0);
else if ('addRule' in style)
    style.addRule('p', 'margin: 0', 0);


I know this is a old thread but i was looking for a solution to insert CSS styles dynamicly that works with all common/major browsers. I want to share my solution with you. The solution of david doesn't work well (sorry). I have made a tooltip javascript/jQuery class that can work with inline styles for example but can also work with CSS styled styles. (offtopic: Also the class can auto align tooltips like the default tooltips).

Maybe you wonder what the benefits are when you insert CSS like the example above. Well, you don't need an extra CSS file with the styles and you can dynamicly add styles from script and when you working with images you can dynamicly change the path to the images if you want (so you don't need to change any file). Also you can insert the styles ABOVE other stylesheets/style rules and the aplied style rules can be modified in the other stylesheets below (this is not possible when you use inline styles or when placing the inserted rules BELOW any existing stylesheet).

This function works with Opera/Firefox/IE7/IE8/IE9/Chrome/Safari (without any hack applied!):

    function addHtmlStyles( sCss, oBefore ) 
    {
     var oHead = document.getElementsByTagName('head')[0];
     if( !oHead || oHead == null ) 
      { return false; }

     var bResult = false,
         oStyle = document.createElement('style');
     oStyle.type = 'text/css';
     oStyle.rel = 'stylesheet';
     oStyle.media = 'screen';

     if( typeof oStyle.styleSheet == 'object' ) 
      {  // IE route (and opera)
        try{ oStyle.styleSheet.cssText = sCss; bResult = true; }
        catch(e) {}  
      }
     else { 
             // Mozilla route
            try{ oStyle.innerHTML = sCss; bResult = true; }
            catch(e) {};
            if( !bResult )
            {
               // Webkit route
              try{ oStyle.innerText = sCss; bResult = true; }
              catch(e) {};
            }
          }

     if( bResult )
     {
      try 
      {
      if( typeof oBefore == 'object' )
       { oHead.insertBefore(oStyle, oBefore ); }
      else { oHead.appendChild(oStyle); }
      }
      catch(e) { bResult = false; }
     }

 return bResult;
}

It returns true when ok or false when fail. For example:

var sCss = '#tooltip {background:"#FF0000";}';

// get first stylesheet with jQuery, we don't use $('head') because it not always working
// If there is no stylesheet available, it will be added at the end of the head tag.
var oHead = $(document.getElementsByTagName('head')[0]),
    oFirst = oHead.find('[rel=stylesheet]').get(0);

if( addHtmlStyles( sCss, oFirst ))
 { alert( 'OK' ); }
else { alert( 'NOT OK' ); }

That's all. Hope you like the solution. Greetz, Erwin Haantjes


This has been tested to work on all major browsers (Chrome/Safari/FF/Opera/IE) including IE6,7+8:

function createCSS(css, doc) {
    doc = doc || document;
    var style = doc.createElement("style");
    style.type = "text/css";

    if (!window.opera && 'styleSheet' in style && 'cssText' in style.styleSheet) {
        // Internet Explorer 6-8 don't support adding text nodes to 
        // styles, so use the proprietary `styleSheet.cssText` instead
        style.styleSheet.cssText = css;
    }
    else {
        // Otherwise use the standard method
        style.appendChild(doc.createTextNode(css));
    }

    // Note the `|| document.body` as getting the
    // head doesn't always work on e.g. Safari 1.0
    var head = doc.getElementsByTagName("head")[0] || doc.body;

    // Add the new style of higher priority than the last
    // ones if there's already other elements in the head
    if (head.firstChild) {
        head.insertBefore(style, head.firstChild);
    }
    else {
        head.appendChild(style);
    }
}

As that code is written, it is relative to the document being served so may need to be modified to make it relative to another path, or you could use absolute image paths in the CSS.

EDIT: Removed all the innerHTML references in favour of using the more standard createTextNode when possible and cleaned various things up.


@GlassGost: Weird is not working for you because i test it in several browsers (also on the mobile ones). Maybe it helps to add css when the DOM is ready:

$(document).ready( function()
{
  .......
});

Also sometimes it helps to change the order of loading scripts.

Greetz, Erwin Haantjes


This works fine for me on all current browsers with any type of document (which I assume you must be dealing with multiple documents, or otherwise you wouldn't have a Doc parameter):

function add_css_style(css_rules, document) {
    document = document || self.document;
    var style = document.createElementNS("http://www.w3.org/1999/xhtml", "style");
    style.type = "text/css";
    style.appendChild(document.createTextNode(css_rules));
    document.documentElement.appendChild(style);
}

If you want to use the CSSOM instead:

function add_css_style(css_rules, document) {
    document = document || self.document;
    var stylesheet = document.documentElement.appendChild(
        this.createElementNS("http://www.w3.org/1999/xhtml", "style")
    ).sheet;
    stylesheet.insertRule("@media all{" + rules + "}", 0);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜