从Javascript更改CSS规则集

是否可以动态更改CSS规则集(例如,某些JS会在用户单击某个小部件时更改CSS规则集)

这个特定的CSS规则集适用于页面上的许多元素(通过类选择器),我想在用户单击小部件时对其进行修改,以使所有具有该类的元素都改变。

你可以,但是相当麻烦。 关于如何做到这一点的最好的参考是下面的文章: 完全使用Javascript ( Web档案链接 ) CSS 。

我设法让它与Firefox和IE一起工作 – 我不能在Chrome中,但它似乎支持DOM方法。 ricosrealm也报告说它也可以在Chrome中运行。

这是一个基于完全使用Javascript的Pwn CSS的现代版本。 这是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 ,并使用document.getElementById('my-style') 。 这是一些有用的方法:

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

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

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

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

不幸的是,用JS编辑样式表的API在浏览器中是不一致的。 YUI样式表实用程序试图平滑这些差异,所以你可以使用它。 如果您不想使用YUI,您也可以查看源代码来了解它的工作原理。

我通过链接从@ alex-gyoshev评论尝试代码,但它没有工作

  1. 它在Chrome中使用Google字体的CSS规则失败
  2. 它在FireFox安全检查失败

所以我稍微改了一下,但删除了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! } 

根据你想要达到什么,一个更好的解决方案可能是改变/添加一个类到一个包含的元素(body将做!),并相应地定义类。

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

那么你可以使用

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

(或者你所选择的js框架的包装器)来改变你的类的yourclass ,无论你的wrapper元素是什么。

((括号内)是否有任何方法来阻止SO格式化器假设以#开头的东西是一个注释?)

给你的风格标签一个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)中由名称“#menuItem”查找的规则样式的颜色

更重要的是,你可能有几个不同的课程,你想要改变所有的一次,就像当你在大学转换专业

假设您有四个不同的类,并且您希望将其所有背景颜色设置为相同的值,即某个用户从输入中选择

颜色选择器标签是<input id="bColor" type="color">并且你想改变的类规则被称为#menuItem .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 

虽然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 ) ) 

用一些正则表达式,但在这种情况下,你将不得不逃避特殊字符。