角度6:如何动态更改页面背景颜色

时间:2018-09-19 07:17:26

标签: css angular background-color

我正在使用Angular 6应用程序(具有Bootstrap 4),并且需要根据用户输入的页面来更改页面背景颜色。默认值为白色,但对于登录和注册屏幕,页面颜色需要为蓝色。

到目前为止我发现了什么:

  • 在ngAfterViewInit()中使用 this.elementRef.nativeElement.ownerDocument:这种方法使 该应用更容易受到XSS攻击,因此我想避免这种情况。
  • 在app.component.ts中将“视图封装”设置为“无”:这样我就可以 在app.component中设置主体颜色,即向前1步。

所以,现在我的app.component.css中有:

body {
  background-color: blue;
} 

问题: 如何使用变量更改该颜色值(在app.component中)?

  • 使用[ngStyle],我无法达到主体的背景色。
  • 也许使用css变量?但是如何动态更改该CSS变量的值?
  • 我是Sass的新手,但这可以提供解决方案吗?
  

我的问题与该主题的其他问题不同,因为我需要能够动态更改颜色值。

4 个答案:

答案 0 :(得分:3)

使用render2并使用文档对象将类设置为正文

app.component.ts

constructor(private renderer: Renderer2) {
this.renderer.addClass(document.body, 'body-class');
}

注意:如果要切换班级,只需在分配新班级之前删除上一个班级

答案 1 :(得分:1)

我的操作方式取决于路线。定义路线时,可以添加其他数据,例如类名。

当路线更改时(例如,通过导航),活动路线中的数据可用于在body标签上设置类别。

这是实现此目标的方法

  1. 更新styles.css以为正文添加不同的类:
body {
  ...
}

body.red {
  background-color: #ff8181;
}

body.blue {
  background-color: #a0c3ee;
}
  1. 更新路线以添加其他数据,并指定主体类名称。添加额外的数据属性,例如bodyClass
const routes: Routes = [
  { path: '', component: DefaultComponent },
  { path: 'red', component: RedComponent, data: { bodyClass: 'red' } },
  { path: 'blue', component: BlueComponent, data: { bodyClass: 'blue' } }
];
  1. 编写代码以读取bodyClass并在发生导航时将类设置为body元素。这可以在app.component.ts中完成:
@Component({
  selector: 'app-root',
  template: `
    <div>
      <router-outlet></router-outlet>
      <app-menu></app-menu>
    </div>
  `
})
export class AppComponent implements OnInit {
  constructor(
    @Inject(DOCUMENT) private document, 
    private renderer: Renderer2, 
    private router: Router, 
    private activatedRoute: ActivatedRoute) {
  }

  ngOnInit() {
    this.router.events
      .pipe(filter((event) => event instanceof NavigationEnd))
      .pipe(map(() => this.activatedRoute))
      .pipe(map((route) => {
        while (route.firstChild) {
          route = route.firstChild;
        }
        return route;
      }))
      .pipe(filter((route) => route.outlet === 'primary'))
      .pipe(mergeMap((route) => route.data))
      .subscribe((event) => this.updateBodyClass(event.bodyClass));
  }

  private updateBodyClass(customBodyClass?: string) {
    this.renderer.setAttribute(this.document?.body, 'class', '');
    if (customBodyClass) {
      this.renderer.addClass(this.document?.body, customBodyClass);
    }
  }
}

这是StackBlitz上的一个演示:https://stackblitz.com/edit/angular-ivy-rs1tai

答案 2 :(得分:0)

为什么不仅仅根据不同的背景色定义一个单独的类?例如:

.blue {
  background: blue
}

.green {
  background: green
}

.grey {
  background: grey
}

然后使用ng-class或ngClass在body上设置这些类,无论您基于页面使用哪种约定。这应该很容易实现。

答案 3 :(得分:0)

我最喜欢做这种事情的方法是根据路由向html标签添加一个类。例如,我们在基本布局组件中有一些代码(可以将其放在根组件中),可以在ngOnInit内部进行此操作:

let wrapper = ''
const path = this.activatedRoute.snapshot.routeConfig.path
wrapper += this.tidyPath(path)
if (wrapper !== '') wrapper += '-'
const childPath = this.activatedRoute.snapshot.firstChild.routeConfig.path
wrapper += this.tidyPath(childPath)
this.routeWrapperCssClass = wrapper
$('html').addClass(this.routeWrapperCssClass)

这会将一个类添加到您的html标记中,使其看起来像这样(尽管您可能必须调整此代码以适合您的应用):

<html class="registration">
    ....
</html>

只要更改路线,班级就会立即更新。

现在您可以在主样式表中执行此操作:

body {
    background-color: pink;
}

html.registration body {
    background-color: yellow;
}

您还可以根据添加到html标记中的类进行隐藏元素之类的操作,例如:

.navbar {
  display: block;
}

html.registration .navbar {
  display: none;
}

因为您始终知道通过CSS进行完全控制所处的路线。

PS,您可能希望使用render2而不是jQuery来进行DOM操作-请参阅本文... https://alligator.io/angular/using-renderer2 ...以前我自己从未使用过它,但几乎与jQuery语法相同-感谢Pratap AK的回答为此