是否可以使用 JavaScript 更改 CSS 样式表?(不是对象的样式,而是样式表本身)

IT技术 javascript html css stylesheet alter
2021-02-08 03:17:26

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

不是在谈论:

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

AM谈论改变:

#id {
    param: value;
}

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

5个回答

截至 2011 年

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

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

截至 2016 年

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

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

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

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

讨厌它让我等待 11 分钟来正确回答这个问题。这正是我正在寻找的。谢谢。
2021-03-20 03:17:26
链接现在似乎已损坏...任何人都可以编辑此答案并提供曾经在提供的链接中找到的内容的摘要吗?(注意:我正在工作,因此该站点可能只是被阻止了,但无论哪种方式,如果可能,都应将内容发布在这里)。
2021-03-21 03:17:26
请注意,该页面已有 4 年历史,从那时起发生了相当大的变化。例如,在 Firefox 5 中,selectors of the rules according to your browser显示0 = body.
2021-03-29 03:17:26
@MathieuRodic 有效。我的工作网络似乎有问题。我仍然认为在答案中至少包含摘要级别的详细信息是一个好主意,其他人可能无法访问该链接,但这只是我的意见。
2021-03-29 03:17:26
这不再是事实。我的回答
2021-04-09 03:17:26

我们可以使用的组合.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");

演示

另外值得注意的是,由于小写,诸如此类的属性backgroundPosition将不起作用。这还需要转换为其带连字符的等价物 ( background-position) 以与insertRule().
2021-03-22 03:17:26
如果您的浏览器在修改样式时没有更新,您可以在重新添加样式之前删除该样式。为此,请更改for循环并添加s.deleteRule(i)和删除return语句。
2021-03-25 03:17:26
这不符合 OP 的预期。编辑后的规则被分配给在检查器中看到的 <style> 对象,而不是实际的样式表。
2021-04-06 03:17:26
如果您在使用旧浏览器时遇到问题,更改.cssRules.rules可能会有所帮助。您也可以省略.insertRulefor Chrome的第二个参数,但其他浏览器(如 FF)需要它
2021-04-11 03:17:26

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

这是一个好主意。今晚我们将测试各种做事方式,并以最适合我们的方式返回:)
2021-03-22 03:17:26

更改样式规则中的属性

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>

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