【问题标题】:Angular 6: How to change page background-color dynamicallyAngular 6:如何动态更改页面背景颜色
【发布时间】:2022-02-09 14:01:11
【问题描述】:

我在 Angular 6 应用程序(使用 Bootstrap 4)上工作,需要根据用户输入的页面更改页面背景颜色。默认为白色,但登录和注册界面的页面颜色需要为蓝色。

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

  • 在 ngAfterViewInit() 中使用 this.elementRef.nativeElement.ownerDocument:这种方法使 应用更容易受到 XSS 攻击,我想避免这种情况。
  • 在 app.component.ts 中将 View Encapsulation 设置为 None:这样我可以 在 app.component 中设置 body 颜色,即向前迈出 1 步。

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

body {
  background-color: blue;
} 

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

  • 使用 [ngStyle] 我无法达到正文背景颜色。
  • 也许使用 css 变量?但是如何动态更改该 css 变量的值?
  • 我是 Sass 的新手,但这是否能提供解决方案?

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

【问题讨论】:

标签: css angular background-color


【解决方案1】:

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

app.component.ts

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

注意:如果您要切换课程,只需在分配新课程之前删除以前的课程

【讨论】:

  • 工作得很好。
【解决方案2】:

我这样做的方式是基于路线。在定义路由时,您可以添加额外的数据,例如类名。

当路由改变时(即通过导航),来自活动路由的数据可用于在 body 标签上设置类。

这就是你可以实现的方法

  1. 更新styles.css 为body 添加不同的类:
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

【讨论】:

    【解决方案3】:

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

    .blue {
      background: blue
    }
    
    .green {
      background: green
    }
    
    .grey {
      background: grey
    }
    

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

    【讨论】:

    • 感谢您的想法:但是 ngClass 与 ngStyle 有相同的问题:我无法到达身体
    【解决方案4】:

    我最喜欢做这样的事情的方法是根据路由向 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 A.K 对此的回答

    【讨论】:

      【解决方案5】:

      我个人替换:

      <body>
      <app-root></app-root>
      </body>
      

      <app-root></app-root>
      

      然后我一直在组件上添加主体,或者如果我有多个 router-outlets 我将它添加到 app.component.css

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-04
        • 2014-04-05
        • 2013-09-15
        • 1970-01-01
        • 2018-03-22
        • 2013-07-11
        • 2015-12-17
        相关资源
        最近更新 更多