简体   繁体   English

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

[英]Is it possible to alter a CSS stylesheet using JavaScript? (NOT the style of an object, but the stylesheet itself)

Is it possible to alter a CSS stylesheet using JavaScript?是否可以使用 JavaScript 更改 CSS 样式表?

I am NOT talking about:不是在谈论:

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

I AM talking about altering:的是改变:

#id {
    param: value;
}

besides doing something dirty (which we haven't tried yet btw), like creating a new object in the head, innerHTML a style tag in there, etc. Although this, even if it did work, would pose a few issues as the style block is already defined elsewhere, and I'm not sure when/if the browser would even parse a dynamically created style block?除了做一些肮脏的事情(顺便说一句,我们还没有尝试过),比如在头部创建一个新的 object,在里面创建一个样式标签 innerHTML,等等。尽管这样,即使它确实有效,也会带来一些问题作为样式块已经在别处定义,我不确定浏览器何时/是否会解析动态创建的样式块?

As of 2011截至 2011 年

Yes you can, but you will be facing cross-browser compatibility issues:是的,您可以,但您将面临跨浏览器兼容性问题:

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

As of 2016截至 2016 年

Browser support has improved a lot (every browser is supported, including IE9+).浏览器支持有了很大改进(支持所有浏览器,包括 IE9+)。

  • The insertRule() method allows dynamic addition of rules to a stylesheet. insertRule()方法允许向样式表动态添加规则。

  • With deleteRule() , you can remove existing rules from a stylesheet.使用deleteRule() ,您可以从样式表中删除现有规则。

  • Rules within a stylesheet can be accessed via the cssRules attributes of a stylesheet.样式表中的规则可以通过样式表的cssRules属性访问。

We can use a combination of .insertRule and .cssRules to be able to do this all the way back to IE9:我们可以使用.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 < s.cssRules.length; i++) {
        var rule = s.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");

Demo演示

When I want to programmatically add a bunch of styles to an object, I find it easier to programmatically add a class to the object (such class has styles asscociated with it in your CSS). When I want to programmatically add a bunch of styles to an object, I find it easier to programmatically add a class to the object (such class has styles asscociated with it in your CSS). You can control the precedence order in your CSS so the new styles from the new class can override things you had previously.您可以在 CSS 中控制优先顺序,因此来自新 class 的新 styles 可以覆盖您之前的内容。 This is generally much easier than modifying a stylesheet directly and works perfectly cross-browser.这通常比直接修改样式表容易得多,并且可以完美地跨浏览器工作。

change a property in a style rule更改样式规则中的属性

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

    }

DEMO演示

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

change the style book with the title chat_inicio with the selector .contenido.mensajes the property of the style width to 475px使用选择器.contenido.mensajes将标题为chat_inicio的样式书更改为样式宽度的属性为475px

<script>
     cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>

2020 2020

Some advantages of this method:这种方法的一些优点:

  • Does not require (but allows) stylesheet to be specified.不需要(但允许)指定样式表。
  • Allows multiple styles to be added / modified at once允许一次添加/修改多个 styles
  • Accepts !important attribute接受!important属性
  • Ignores extra whitespace when matching CSS selector匹配 CSS 选择器时忽略额外的空格
  • Changes last matching existing rule, or appends to end of last matching stylesheet.更改最后一个匹配的现有规则,或附加到最后一个匹配样式表的末尾。 (Other answers add/change the first rule which may be then overruled.) (其他答案添加/更改可能会被否决的第一条规则。)

Usage:用法:

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

Method:方法:

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

Demo演示

The method takes three arguments:该方法取三个arguments:

  • selector [String] - CSS selector - eg: '#myDiv'选择器 [字符串] - CSS 选择器 - 例如:'#myDiv'
    Whitespaces are auto-reduced ( .myClass #myDiv will match .myClass #myDiv )空格会自动减少( .myClass #myDiv将匹配.myClass #myDiv
  • rules [CSS String, Object] - eg (either is acceptable):规则 [CSS 字符串,对象] - 例如(任何一个都可以接受):
    • { border: "solid 3px green", color: "white" }
    • 'border: solid 3px green; color: white'
  • sheet (Optional) [String, StyleSheet]表(可选)[字符串,样式表]
    • if empty, all stylesheets will be checked如果为空,将检查所有样式表
    • 'myStyles.css' A relative or absolute URL to sheet 'myStyles.css' 相对或绝对 URL 到工作表
    • document.styleSheets[1] - A reference to a sheet document.styleSheets[1] - 对工作表的引用

Other examples:其他示例:

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

Best solution is最好的解决办法是

Content CSS file:
#casesDndDropdown {
    background: #FFFFFF;
    border: 4px
}

You can override the #casesDndDropdown or any CSS class by defining it in <style> tag inside body,您可以通过在主体内的 <style> 标记中定义它来覆盖#casesDndDropdown或任何CSS class

jQuery
$('<style>#id{background: #428bca;border: 0px}</style>').appendTo('body');

.style.cssText property works, try the code below: .style.cssText 属性有效,请尝试以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0%;
        padding: 0%;
    }

    html {
        --theme-orange: orangered;
        --theme-blue: rgb(67, 67, 197);
        --theme-green: darkgreen;
        --theme-black: black;
        --theme-color: var(--theme-orange);
    }

    body {
        font-family: 'Roboto', sans-serif;
        background-color: rgb(251, 251, 251);
    }

    .nav-bar ul {
        display: flex;
        width: 100%;
        background-color: var(--theme-color);
        flex-wrap: wrap;
        flex-direction: row;
        align-items: center;
        width: 100%;
    }

    .nav-bar ul a {
        text-decoration: none;
        margin: 15px 10px;
    }

    .nav-bar .theme {
        background-color: white;
        display: flex;
        height: fit-content;
        margin-left: auto;
        margin-right: 20px;
        border-radius: 10px;
    }

    .nav-bar .theme .box {
        width: 20px;
        height: 20px;
        border: 1px solid black;
        cursor: pointer;  
    }

    .nav-bar .theme .orange {
        background-color: var(--theme-orange);
    }

    .nav-bar .theme .blue {
        background-color: var(--theme-blue);
    }

    .nav-bar .theme .green {
        background-color: var(--theme-green);
    }

    .nav-bar .theme .black {
        background-color: var(--theme-black);
    }

    .nav-bar ul li {
        color: white;
        font-weight: 500;
        list-style: none;
        padding: 10px 30px;
        background-color: var(--theme-color);
        transition: 0.2s;
    }

    .nav-bar ul li:hover {
        box-shadow: inset 10px 10px 10px -12px;
        scale: 0.95;
    }

</style>
<body>
    <div class="nav-bar">
        <ul>
            <a href=""><li>Home</li></a>
            <a href=""><li>Page 1</li></a>
            <a href=""><li>Page 2</li></a>
            <a href=""><li>About Us</li></a>
            <a href=""><li>Contact Us</li></a>
            <div class="theme">
                <a><div class="box orange" id="orange"></div></a>
                <a><div class="box blue" id="blue"></div></a>
                <a><div class="box green" id="green"></div></a>
                <a><div class="box black" id="black"></div></a>
            </div>
        </ul>
    </div>

    <script>
        function colorChange(color) {
            const htmlTag = document.getElementsByTagName("*")[0];
            htmlTag.style.cssText = `--theme-orange: orangered;
            --theme-blue: rgb(67, 67, 197);
            --theme-green: darkgreen;
            --theme-black: black;
            --theme-color: var(--theme-${color});`;
        }

        function addEventListenerForBox() {
            allBox = document.querySelectorAll('.box');
            allBox.forEach(box => {
                box.addEventListener('click', (event) => {
                    colorChange(event.target.id);
                });
            });
        }

        document.addEventListener('DOMContentLoaded', addEventListenerForBox);
    </script>
</body>
</html>

Result:结果: 在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM