【问题标题】:controlling css with javascript works with Mozilla & Chrome however not with IE使用 javascript 控制 css 适用于 Mozilla 和 Chrome,但不适用于 IE
【发布时间】:2011-02-12 05:00:56
【问题描述】:

我在应用 css(使用文本变量)与 Internet Explorer 一起工作时遇到问题,但它在 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

【问题讨论】:

  • 为什么要这样添加css?
  • @Ken 对服务器的每个文件请求比单独的文件对服务器的负担更大。另外我很无聊。
  • 我很高兴这是一个有趣的问题;否则,我很想仅仅因为“另外,我很无聊”而投票赞成。 :-D
  • 为什么不使用 jQuery 或其他有保证的跨浏览器 js 库?

标签: javascript internet-explorer google-chrome webkit


【解决方案1】:
var style = document.createElement('style');

通过使用 DOM 方法创建元素来添加新样式表和脚本一直是跨浏览器的冒险。这在 IE 或 WebKit 中不起作用。

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

HTMLStyleElement 上没有这样的属性。 <style> 包含内联代码。对于外部样式表,使用<link>。幸运的是,这确实有效:

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

但没有给您提供从脚本插入规则的便捷方式。

您还可以使用document.styleSheets 接口将新规则添加到现有样式表(例如<head> 中的空style)。不幸的是,IE 的界面与这里的标准不太匹配,所以你需要代码分支:

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);

【讨论】:

    【解决方案2】:

    已经过测试,可以在所有主流浏览器(Chrome/Safari/FF/Opera/IE)上运行,包括 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);
        }
    }
    

    在编写该代码时,它是相对于所提供的文档的,因此可能需要对其进行修改以使其相对于另一个路径,或者您可以在 CSS 中使用绝对图像路径。

    编辑:删除所有 innerHTML 引用,以便尽可能使用更标准的 createTextNode 并清理各种内容。

    【讨论】:

    • 这看起来是一个非常合理的答案;并不是说其他​​答案还不错。在我选择它作为接受的答案之前,首先要做一些测试。非常感谢,如果它确实有效。
    • 不需要delete _CSS。它不会导致错误,但不会执行任何操作,因为只有对象的属性可能会被删除。
    • 您应该将 div 替换为 span 以避免创建新行。
    • 如果 head 不存在,只需执行 head = body。它会工作得很好。
    • @xavierm02: 如果<script> 标记之前没有空格,IE6 会给出type mismatch 错误。最后一个空格似乎不需要,所以我删除了它。
    【解决方案3】:

    我知道这是一个旧线程,但我正在寻找一种动态插入 CSS 样式的解决方案,该解决方案适用于所有常见/主要浏览器。我想和你分享我的解决方案。大卫的解决方案效果不佳(对不起)。我制作了一个工具提示 javascript/jQuery 类,它可以使用例如内联样式,但也可以使用 CSS 样式样式。 (题外话:该类也可以像默认工具提示一样自动对齐工具提示)。

    也许你想知道当你像上面的例子那样插入 CSS 有什么好处。好吧,您不需要带有样式的额外 CSS 文件,您可以从脚本动态添加样式,并且在处理图像时,您可以根据需要动态更改图像的路径(因此您不需要更改任何文件)。您还可以在其他样式表/样式规则之上插入样式,并且可以在下面的其他样式表中修改应用的样式规则(当您使用内联样式或将插入的规则放置在任何现有样式表之下时,这是不可能的)。

    此功能适用于 Opera/Firefox/IE7/IE8/IE9/Chrome/Safari(无需任何破解!):

        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;
    }
    

    成功时返回true,失败时返回false。例如:

    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' ); }
    

    就是这样。希望你喜欢这个解决方案。 问候, 欧文·汉杰斯

    【讨论】:

    • 我无法让它与所查看的答案一起工作,但是通过将我的原始代码和你的代码合并到一个新函数中,我得到了它的一半工作,肯定在 firefox 中工作,并且主要在 chrome 中工作。
    • 奇怪的是它现在根本不能在 chrome 中工作,也许它更新了自己或其他东西。
    • 好吧,当我测试它时;它不适用于 Chrome 或 Internet Explorer。此外,我确实将您的头部修复添加到提供的代码中,该代码现在适用于除 IE8 及更早版本之外的所有内容,并且比您的代码更简洁。抱歉,我忘记投票了。自从我测试你的代码以来已经有一段时间了,它现在可能正在使用 chrome,因为它们正在不断更新。按照目前的速度,一半的赏金看起来会发给获得 3 次支持的人,因为我无法在此页面上收到任何代码来使用 IE8 及更早版本。我没有回答这个问题,除非 IE7(希望 IE6)可以工作。
    【解决方案4】:

    @GlassGost:Weird 不适合你,因为我在几个浏览器(也在移动浏览器上)测试了它。也许在 DOM 准备好时添加 css 会有所帮助:

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

    有时更改加载脚本的顺序也会有所帮助。

    问候, 欧文·汉杰斯

    【讨论】:

    • 你到底测试了什么?在我的情况下也是如此;维基百科样式,我似乎无法访问脚本加载时或脚本加载顺序。
    • 我在几个浏览器中测试了函数'addHtmlStyles'。我不明白你的问题。维基百科风格?使用权? Greetz Erwin Haantjes
    【解决方案5】:

    这对我来说适用于所有当前具有任何类型文档的浏览器(我假设您必须处理多个文档,否则您将没有Doc 参数):

    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);
    }
    

    如果您想改用 CSSOM:

    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);
    }
    

    【讨论】:

    • IE8 不适合我(IE7、IE6 我没有检查,但我什么都不期待)
    • 我说的是当前的。 IE9 是当前的 IE。
    猜你喜欢
    • 1970-01-01
    • 2013-07-09
    • 2015-05-07
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    相关资源
    最近更新 更多