在我的CSS文件中,我有一个类:
.test{
background: red;
}
但是在我的应用程序开始时,我想根据服务器响应重新定义此类,以便背景变为蓝色或绿色,具体取决于变量。
将这个类(.test)归结为新颜色是非常重要的,因为我的许多元素已经有了这个类,我不想为它们应用新类。
不确定它是否非常清楚但总结一下,我想从javascript(使用角度2)创建一个适用于整个文档的类。
答案 0 :(得分:1)
编辑(bc我最初对你的要求感到困惑) -
我认为在应用程序加载后修改全局样式文件是一种很好的方法,但如果我错了,请指正。
影子DOM让这很棘手。我将为您的模块提供一个运行时配置变量,然后有条件地将一个类添加到您的应用程序的根组件中。
<div class="outer-app-wrapper" [ngClass]="someValue">
然后在你的全局styles.css文件中,你可以定义.test的所有不同变体。
.someValue1 .test {
background: red;
}
.someValue2 .test {
background: green;
}
.someValue3 .test {
background: yellow;
}
我认为如果你定义styles.css文件中的所有变体,你应该能够避免使用&#39; host-context:&#39;选择器在后代组件中。没有必要在Angular的范围之外的元素中添加任何类,例如&#39; body&#39;元素,只需将其添加到应用程序的最顶层元素,只要后代组件不重新定义测试类,因为它在全局样式表中定义,它应该可以正常工作。
注意 - 如果您不想添加包装元素或修改现有元素,也可以使用@HostBinding将类添加到根组件
答案 1 :(得分:1)
下面的代码将找到作为文档一部分的任何样式规则(包括媒体规则内的规则),并覆盖选择器匹配的任何样式。
您可以在服务实例上调用modifyStyles('.test', { 'background': 'blue' })
,以使.test
类的所有样式都具有蓝色背景。您可能希望使用选择器的运行方式,因为在其当前实现中,任何位于其中任何位置.test
的规则都将更改其背景。您可能更喜欢将正则表达式更改为^ .test $,以使其与.test
和仅匹配 .test
。
@Injectable()
export class CssUpdateService {
constructor( @Inject(DOCUMENT) private document: Document) {
}
modifyStyles(selector: string, styles: any) {
const rulesToUpdate = this.findRules(new RegExp(`\b${selector}\b`, 'g'));
for (let rule of rulesToUpdate) {
for (let key in styles) {
rule.style[key] = styles[key];
}
}
}
/**
* Finds all style rules that match the regular expression
*/
private findRules(re: RegExp) {
let foundRules: CSSStyleRule[] = [];
let ruleListToCheck = Array.prototype.slice.call(this.document.styleSheets);
for (let sheet of ruleListToCheck) {
for (let rule of (<any[]>(sheet.cssRules || sheet.rules || []))) {
if (rule instanceof CSSStyleRule) {
if (re.test(rule.selectorText)) {
foundRules.push(rule);
}
}
else if (rule instanceof CSSMediaRule) {
ruleListToCheck.push(rule);
}
}
}
return foundRules;
}
}