javascript - 头上有重复的样式和很多 <style> 元素

标签 javascript html angular angular-material2

我对 angular-material2 组件非常满意,但有一些我不理解的奇怪行为,而且它们没有适当的文档,尤其是关于填充和自定义它们的组件。

我的项目看起来像:

.src
  --app
    --components
      --login-component
           login-component.html
           login-component.scss
           login-component.js
      --login-component
            home-component.html
            home-component.scss
            home-component.js
       --and so on ...
    app.component.html
    app.component.scss
    app.component.ts
    app.module.ts
    app.routing.ts
    --assets
    --environments
    --scss
      styles.scss
      _material2-theme.scss
      _variables-scss
      _utilities.scss
      _reset.scss
   favicon
   index.html
   and so on ....

在 angular-cli.json 中我修改了样式以查看 scss/style.scss

...
"styles": [
        "scss/styles.scss"
      ]
...

_material2-theme.scss 看起来像:

//////////////////////* THEMES */ Custom Blue Theme*/
@import '~@angular/material/theming';
@include mat-core();
$app-primary: mat-palette($mat-light-blue);
$app-accent:  mat-palette($mat-light-blue, A200, A100, A400);
$app-theme:   mat-light-theme($app-primary, $app-accent);
@include angular-material-theme($app-theme);

/*default palette forground/background*/
$light-foreground-palette: map-get($app-theme, foreground);
$light-background-palette: map-get($app-theme, background);

$primary: map-get($app-theme, primary);
$accent: map-get($app-theme, accent);

在 style.scss 里面,我正在导入所有要用 scss cli 编译器编译的东西

//////////////////////* CUSTOM */
@import "_material2-theme.scss";
@import "_reset.scss";
@import "_utilities.scss";
 //////////////////////* COMPONENTS */
 @import "~app/components/login/login.component.scss";

我的问题是在 scss 编译后我们在 html head 中有许多样式标签,其中一些是重复的并且看起来像:

enter image description here

一切似乎都以一种样式编译,添加到 head 中(具有 type 属性的样式),然后每个 scss 组件拆分为每个 css 组件,在 head 中具有单独的样式,这很奇怪。我做错了什么,或者只是 material2 的工作方式?

最佳答案

您看到的行为是由为 Material 组件定义的 ViewEncapsulation.Emulated 引起的。

首先,您不需要将组件的样式添加到全局样式"scss/styles.scss":

//////////////////////* COMPONENTS */
@import "~app/components/login/login.component.scss";

如果这样做,除了您的样式会被复制之外,您还会失去样式封装,因为为 components/login/login.component.scss 添加的样式将成为全局样式。

现在,对于为什么有很多 style 元素的问题。当你使用 ViewEncapsulation.Emulated 时,它是一种默认的 View 封装模式,Angular 会将每个组件的样式放入它自己的 style 标签中,并为组件模板内的元素添加属性。在 Material 中,所有组件都使用模拟封装模式,因此为每个组件添加了 style 标签。

如果您为组件添加 @Component({..., encapsulation: ViewEncapsulation.Native }),您将看到组件的 style 将被删除.

Here is the logic添加 style 标签:

export class DomSharedStylesHost extends SharedStylesHost implements OnDestroy {
  ...
  private _addStylesToHost(styles: Set<string>, host: Node): void {
    styles.forEach((style: string) => {
      const styleEl = this._doc.createElement('style');  <--- creates a style element
      styleEl.textContent = style;
      this._styleNodes.add(host.appendChild(styleEl));
    });
  }

关于javascript - 头上有重复的样式和很多 &lt;style&gt; 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48114825/

相关文章:

javascript - 在 JavaScript + jQuery 网络应用程序中将 UI 与模型数据链接的最佳实践

javascript - 将 $_GET [id] 传递给刷新

Javascript 添加 ID 和哈希链接到新 ID

html - CSS 位置转换和显示 :none

javascript - Angular 9如何使用debouncetime进行输入更改事件(keyup)

javascript - $index 在 Nativescript 中不起作用

javascript - react-native run-ios 需要永远构建,有时永远不会构建

javascript - 用另一个 HTML 页面替换 <div>

angular - ng build --prod (AOT) 时装饰器不支持函数调用

javascript - 如何从列表中过滤数据并以 Angular 从数据中删除现有房间