45

是否可以使用 JavaScript 更改 CSS 样式表?

不是在谈论:

document.getElementById('id').style._____='.....';

的是改变:

#id {
    param: value;
}

除了做一些肮脏的事情(顺便说一句,我们还没有尝试过),比如在头部创建一个新对象,innerHTML 一个样式标签,等等。尽管这样,即使它确实有效,也会带来一些问题作为样式块已经在别处定义了,我不确定浏览器何时/是否会解析动态创建的样式块?

4

5 回答 5

41

截至 2011 年

是的,您可以,但您将面临跨浏览器兼容性问题:

http://www.quirksmode.org/dom/changess.html

截至 2016 年

浏览器支持有了很大改进(支持所有浏览器,包括 IE9+)。

  • insertRule()方法允许向样式表动态添加规则。

  • 使用deleteRule(),您可以从样式表中删除现有规则。

  • 样式表中的规则可以通过cssRules样式表的属性来访问。

于 2011-07-08T05:48:08.420 回答
16

我们可以使用.insertRule和的组合.cssRules来做到这一点,回到 IE9:

function changeStylesheetRule(stylesheet, selector, property, value) {
    // Make the strings lowercase
    selector = selector.toLowerCase();
    property = property.toLowerCase();
    value = value.toLowerCase();
    
    // Change it if it exists
    for(var i = 0; i < stylesheet.cssRules.length; i++) {
        var rule = stylesheet.cssRules[i];
        if(rule.selectorText === selector) {
            rule.style[property] = value;
            return;
        }
    }
  
    // Add it if it does not
    stylesheet.insertRule(selector + " { " + property + ": " + value + "; }", 0);
}

// Used like so:
changeStylesheetRule(s, "body", "color", "rebeccapurple");

演示

于 2016-06-30T20:58:22.477 回答
4

当我想以编程方式向一个对象添加一堆样式时,我发现以编程方式向对象添加一个类更容易(这样的类在您的 CSS 中具有与之关联的样式)。您可以控制 CSS 中的优先顺序,以便新类中的新样式可以覆盖您之前的内容。这通常比直接修改样式表容易得多,并且可以完美地跨浏览器工作。

于 2011-07-08T09:18:35.050 回答
2

2020

这种方法的一些优点:

  • 不需要(但允许)指定样式表。
  • 允许一次添加/修改多个样式
  • 接受!important属性
  • 匹配 CSS 选择器时忽略多余的空格
  • 更改最后一个匹配的现有规则,或附加到最后一个匹配样式表的末尾。(其他答案添加/更改可能会被否决的第一条规则。)

用法:

adjustCSSRules('#myDiv', 'width: 300px !important');

方法:

function adjustCSSRules(selector, props, sheets){

    // get stylesheet(s)
    if (!sheets) sheets = [...document.styleSheets];
    else if (sheets.sup){    // sheets is a string
        let absoluteURL = new URL(sheets, document.baseURI).href;
        sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
        }
    else sheets = [sheets];  // sheets is a stylesheet

    // CSS (& HTML) reduce spaces in selector to one.
    selector = selector.replace(/\s+/g, ' ');
    const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
    let rule = sheets.map(findRule).filter(i=>i).pop()

    const propsArr = props.sup
        ? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
        : Object.entries(props);                              // from Object

    if (rule) for (let [prop, val] of propsArr){
        // rule.style[prop] = val; is against the spec, and does not support !important.
        rule.style.setProperty(prop, ...val.split(/ *!(?=important)/));
        }
    else {
        sheet = sheets.pop();
        if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
        sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
        }
    }

演示

该方法接受三个参数:

  • 选择器 [String] - CSS 选择器 - 例如:'#myDiv'
    空格会自动减少(.myClass #myDiv将匹配.myClass #myDiv
  • 规则 [CSS 字符串,对象] - 例如(任何一个都可以接受):
    • { border: "solid 3px green", color: "white" }
    • 'border: solid 3px green; color: white'
  • 表(可选)[字符串,样式表]
    • 如果为空,将检查所有样式表
    • 'myStyles.css' 工作表的相对或绝对 URL
    • document.styleSheets[1]- 对工作表的引用

其他示例:

adjustCSSRules('#myDiv', {width: '30px'}); // all stylesheets
adjustCSSRules('#myDiv', 'width: 30px', 'style.css'); // style.css only  
adjustCSSRules('#myDiv  .myClass', 'width: 30px', document.styleSheets[0]); // only first stylesheet
于 2020-10-16T09:55:42.463 回答
2

更改样式规则中的属性

function change_css_style (titulo,selector,propiedad,valor) {        
        let i=0;
        while (i<document.styleSheets.length) {
            if (document.styleSheets[i].title==titulo) {
                let y=0;
                while (y<document.styleSheets[i].cssRules.length) {
                    if (document.styleSheets[i].cssRules[y].selectorText==selector) {                                               
                        document.styleSheets[i].cssRules[y].style[propiedad] = valor;                                                                       
                        y = document.styleSheets[i].cssRules.length;
                    } 
                    y++;
                }               
                i=document.styleSheets.length;
            } 
            i++;
        }

    }

演示

<style title="chat_inicio">
    .contenido .mensajes {
          width: 100px;
          height: 300px;    
    }
</style>

使用选择器更改标题为chat_inicio的样式书.contenido .mensajes样式宽度的属性为475px

<script>
     cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>
于 2019-12-26T11:26:40.323 回答