从 Javascript 更改 CSS 规则集
Posted
技术标签:
【中文标题】从 Javascript 更改 CSS 规则集【英文标题】:Changing a CSS rule-set from Javascript 【发布时间】:2010-11-27 09:50:55 【问题描述】:是否可以动态更改 CSS 规则集(即当用户单击小部件时某些 JS 会更改 CSS 规则集)
这个特定的 CSS 规则集应用于页面上的许多元素(通过类选择器),我想在用户单击小部件时对其进行修改,以便所有元素都具有 类强>改变。
【问题讨论】:
查看一些答案,您的问题的含义似乎有些混乱。不存在“CSS 类”这一事实无济于事,但通常以这种方式错误描述了两种不同的事物。一个是“一个 html 类”,但我认为您指的是另一个 - CSS 规则集(在这种情况下,带有一个类选择器)。 我的意思是为类选择器设置 CSS 规则 相关 - Setting CSS pseudo-class rules from javascript 【参考方案1】:可以,但是比较麻烦。如何做到这一点的最佳参考是以下文章:Totally Pwn CSS with Javascript (web archive link)。
我设法让它与 Firefox 和 IE 一起工作 - 我不能在 Chrome 中,虽然它似乎支持 DOM 方法。ricosrealm 报告说它也可以在 Chrome 中工作.
【讨论】:
以下是来自 MDC 的一些参考资料:developer.mozilla.org/en/DOM/document.styleSheetsdeveloper.mozilla.org/En/DOM/Stylesheet 在 Chrome 11 中测试。效果很好。 那个指南太棒了!!!我已经在最新的 Firefox 和 Chrome 上测试过它,它就像一个魅力!!! 链接已损坏(数据库已关闭),但看起来像someone turned it into a library。 这个答案已经过时了。查看现代解决方案here【参考方案2】:虽然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 ) )
使用一些正则表达式,但在这种情况下您必须转义特殊字符。
【讨论】:
关于你答案的最后一部分,我认为应该使用 match 以外的东西来解释多个类名,以任何顺序。例如,"foo bar".match("foo bar") 将返回 "foo bar",但 "foo bar".match("bar foo") 将返回 null。也许用空格分隔并检查 for 循环中的所有类名会起作用(但是,应该忽略前导/尾随空格,并注意不要从某处的额外空间中获取数组中的空字符串)。参考:W3 Semantics【参考方案3】:根据您要实现的目标,更好的解决方案可能是将类更改/添加到包含元素(body 可以!),并相应地定义类。
.yourclass color: black
#wrapper.foo .yourclass color: red
#wrapper.bar .yourclass color: blue
那么你就可以使用
document.getElementById('wrapper').className='foo';
(或您选择的 js 框架的包装器)以更改带有 yourclass
类的所有内容,无论您的 wrapper
元素是什么。
【讨论】:
回应您的括号:是的,有一种方法可以明确指定代码语言 (meta.stackexchange.com/questions/63800/…)【参考方案4】:遗憾的是,用于使用 JS 编辑样式表的 API 在浏览器中并不一致。 YUI Stylesheet Utility 试图消除这些差异,以便您可以使用它。如果您不想使用 YUI 本身,也可以查看 the source code 以了解它是如何工作的。
【讨论】:
这仍然有效吗? 网站上写着“已弃用”和“不要将其用于新项目”,所以我最好的猜测是没有。【参考方案5】:我通过@alex-gyoshev 评论中的链接尝试了代码,但它不起作用
-
它在 Chrome 中使用 Google 字体的 CSS 规则失败
FireFox 安全检查失败
所以我稍微改变了它,但删除了delete
功能,因为我不需要它。已在 IE 11、FireFox 32、Chrome 37 和 Opera 26 中检查。
function getCs-s-rule(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!
【讨论】:
css 规则不区分大小写? google.ru/search?q=CSS+case+sensitive -> w3.org/TR/CSS2/syndata.html#characters "所有 CSS 语法在 ASCII 范围内都不区分大小写(即 [az] 和 [AZ] 是等效的),除了不在控制 CSS。”【参考方案6】:这是一个基于 Totally Pwn CSS 和 Javascript 的现代版本。这是 ES6,我希望不要介意。
function getCs-s-rule(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 = getCs-s-rule('#header');
header.style.backgroundColor = 'red';
还 document.styleSheets 列出 CSSStylesSheets 对象的引用。访问页面中特定 sytleSheet 的其他方法是通过将 id 分配给 html 代码中的 style 或 link 元素,并获取它在 javascript 中使用 document.getElementById('my-style').sheet。这是一些有用的方法:
主要浏览器和 IE9+: insertRule()、deleteRule()、removeProperty()。
主要浏览器,火狐?和 IE9+: setProperty()。
<stye id="my-style" ...
....
var myStyle = document.getElementById('my-style').sheet
myStyle.insertRule('#header background: red; ', 0);
也可以动态创建一个新的样式元素来存储动态创建的样式,我认为应该是避免冲突的方法。
【讨论】:
这很好用!我只是在调用 find 之前添加检查styleSheet.cssRules
的存在。【参考方案7】:
给你的风格标签一个ID,比如<style id="ssID">
如果有人正在为你制作你的风格
告诉那个人给样式标签一个 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];
现在您有了样式表中所有内容的哈希表 - 请注意,有些值将是 undefined,但不是 你关心的任何事情
例如,如果您有一个名为 #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
【讨论】:
只是路过,但大多数时候这里的人们将解释发布在他们的代码上方,而不是像 cmets 那样混入代码中。您将来可能会考虑这样做。 这是一个非常有用的想法,但请记住,ss0.sheet.rules 可能有一个带有“length”键的元素,甚至可能有“item”,具体取决于浏览器等。跨度> 【参考方案8】:您可以按如下方式在文档样式表中编辑 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>
【讨论】:
以上是关于从 Javascript 更改 CSS 规则集的主要内容,如果未能解决你的问题,请参考以下文章
哪个 JavaScript 框架可以搜索 CSS 样式表规则并编辑它们的属性?