从Javascript更改CSS规则集

时间:2009-09-11 06:06:33

标签: javascript css

是否可以动态更改CSS规则集(即某些JS会在用户单击窗口小部件时更改CSS规则集)

这个特殊的CSS规则集应用于页面上的许多元素(通过类选择器),我想在用户单击小部件时修改它,以便所有具有类的元素改变。

8 个答案:

答案 0 :(得分:32)

你可以,但它相当麻烦。有关如何执行此操作的最佳参考是以下文章:Totally Pwn CSS with Javascriptweb archive link)。

我设法让它与Firefox和IE一起工作 - 我不能在Chrome中,虽然看起来它支持DOM方法。 ricosrealm报告它在Chrome中有效也是。

答案 1 :(得分:7)

这是一个基于Totally Pwn CSS和Javascript的现代版本。这是ES6我希望不介意。

function getCSSRule(ruleName) {
    ruleName = ruleName.toLowerCase();
    var result = null;
    var find = Array.prototype.find;

    find.call(document.styleSheets, styleSheet => {
        result = find.call(styleSheet.cssRules, cssRule => {
            return cssRule instanceof CSSStyleRule 
                && cssRule.selectorText.toLowerCase() == ruleName;
        });
        return result != null;
    });
    return result;
}

此函数返回一个CSSStyleRule,你可以这样使用:

var header = getCSSRule('#header');
header.style.backgroundColor = 'red';

document.styleSheets 列出了CSSStylesSheets对象的引用。访问页面中特定sytleSheet的其他方法是在html代码中为样式链接元素指定 id ,然后获取它在javascript中使用 document.getElementById('my-style')。sheet 。这是一些有用的方法:

主要浏览器和IE9 +: insertRule(),deleteRule(),removeProperty()。

主要浏览器,Firefox?和IE9 +: setProperty()。

<stye id="my-style" ...
....
var myStyle = document.getElementById('my-style').sheet
myStyle.insertRule('#header { background: red; }', 0);

也可以动态创建一个新的样式元素来存储动态创建的样式,我认为应该是避免冲突的方法。

答案 2 :(得分:4)

可疑,使用JS编辑样式表的API在浏览器中并不一致。 YUI Stylesheet Utility尝试平滑这些差异,以便您可以使用它。如果您不想使用YUI本身,也可以查看the source code以了解它是如何工作的。

答案 3 :(得分:4)

我通过@ alex-gyoshev评论中的链接尝试了代码,但它无法正常工作

  1. 在Chrome中使用Google字体的CSS规则失败
  2. 在FireFox安全检查中失败
  3. 所以我稍微改了一下,但删除了delete功能,因为我不需要它。在IE 11,FireFox 32,Chrome 37和Opera 26中查看。

    function getCSSRule(ruleName) { // Return requested style object
      ruleName = ruleName.toLowerCase(); // Convert test string to lower case.
      var styleSheet;
      var i, ii;
      var cssRule = false; // Initialize cssRule. 
      var cssRules;
      if (document.styleSheets) { // If browser can play with stylesheets
        for (i = 0; i < document.styleSheets.length; i++) { // For each stylesheet
          styleSheet = document.styleSheets[i];
          if (!styleSheet.href) {
            if (styleSheet.cssRules) { // Browser uses cssRules?
              cssRules = styleSheet.cssRules; // Yes --Mozilla Style
            } else { // Browser usses rules?
              cssRules = styleSheet.rules; // Yes IE style. 
            } // End IE check.
            if (cssRules) {
              for (ii = 0; ii < cssRules.length; ii++) {
                cssRule = cssRules[ii];
                if (cssRule) { // If we found a rule...
                  // console.log(cssRule);
                  if (cssRule.selectorText) {
                    console.log(cssRule.selectorText);
                    if (cssRule.selectorText.toLowerCase() == ruleName) { //  match ruleName?
                      return cssRule; // return the style object.
                    }
                  }
                }
              }
            }
          }
        }
      }
      return false; // we found NOTHING!
    }
    

答案 4 :(得分:3)

根据您要实现的目标,更好的解决方案可能是将类更改/添加到包含元素(正文将执行!),并相应地定义类。

.yourclass { color: black }
#wrapper.foo .yourclass { color: red }
#wrapper.bar .yourclass { color: blue }

然后你可以使用

document.getElementById('wrapper').className='foo';

(或者你选择的js框架的包装器)用你的yourclass元素内的wrapper类更改所有内容。

答案 5 :(得分:1)

为您的样式标记添加ID,例如<style id="ssID"> 如果someonelse正在为你制作你的风格 告诉那个人给风格标签一个id - 这样你就可以直接访问它 争先恐后地想知道它的指数是什么

// create a hash table
var cssHash = {};

// loop through and populate the hash table
for (let i in (r = ss0.sheet.rules)) {

    // selectorText is the name of the rule - set the value equal to the rule
    cssHash[r[i].selectorText] = r[i];

}

现在你有一个样式表中所有东西的哈希表 - 请注意,某些值将未定义,但不适用于 你关心的任何事情

例如,如果您有一个名为 #menuItem 的类 并且您想将其颜色更改为黑色,请执行此操作

cssHash['#menuItem'].style.color = #000;

该行将设置规则样式的颜色 其索引在哈希表中查找(cssHash) 名称&#39;#menuItem&#39;

更重要的是,你可能有几个不同的 您想要一次更改的类 有点像你在大学里转换专业时

让我们说你有四个不同的班级 你想要设置他们所有的背景颜色 相同的值,某些用户从输入中选择

颜色选择器标记为<input id="bColor" type="color"> 并调用要更改的类规则 #menIItem .homeAddr span #vacuum:hover

// create a listener for that color selector
bColor.addEventListener('input', function (e) {

  // loop through a split list of the four class names
  '#menuItem .homeAddr span #vacuum:hover'.split(' ').forEach(function (obj) {

    // use the hash table to look up the index of each name
    // and set the background color equal to the color input's value
    cssHash[obj].style.backgroundColor = bColor.value;

  });

}, false); // false added here for the sake of non-brevity

答案 6 :(得分:1)

您可以按以下方式在文档样式表中编辑CLASS

[...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
     .style.background= 'red';

function edit() {
  [...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
    .style.background= 'red';
}
.box {
  margin: 10px;
  padding: 10px;
  background: yellow;
}
<button onclick="edit()" >Click me</button>
<div class="box" >My box 1</div>
<div class="box" >My box 2</div>
<div class="box" >My box 3</div>

答案 7 :(得分:0)

虽然setAttribute很好,但在大多数浏览器中都有一种标准的方法:

htmlElement.className = 'someClass';

要在许多元素上执行此操作,您需要一个跨浏览器解决方案:

function getElementsByClassName( className, context, tagName ) {
  context = context || document;
  if ( typeof context.getElementsByClassName === 'function' )
    return context.getElementsByClassName( className );

  if ( typeof context.getElementsByTagName !== 'function' )
    return [];

  var elements = typeof tagName === 'string' ? context.getElementsByTagName( tagName ) :
    context.getElementsByTagName('*'),
  ret = [];
  for ( var i = 0, il = elements.length; i < il; i++ )
    if ( elements[ i ].className.match( className ) )
      ret.push( elements[ i ] );

  return ret;
}

var elements = getElementsByClassName('someClass');

for ( var i = 0, il = elements.length; i < il; i++ )
  elements[ i ].className = 'newClass';

您可能想要替换该行:

if ( elements[ i ].className.match( className ) )

使用一些正则表达式,但在这种情况下你必须转义特殊字符。