在Angular中,innerHTML中的样式无法运行

167
我将 HTML 作为 innerHtml 传递给我的视图。以下是我的视图:
<div [innerHTML]="someHtmlCode"></div>

如果我通过以下代码,它可以正常工作。

this.someHtmlCode = "<div><b>This is my HTML.</b></div>"

如果我传递包含颜色的以下代码,它不起作用。

 this.someHtmlCode = '<div style="background-color: blue;"><b>This is my HTML.</b></div>';

3
好的,我会尽力以最简洁的方式翻译以下内容:使用以下内容...... - SuReSh
4
这可能会帮到您。 - Neenu Chandran
请查看以下关于样式的理想用例:https://angular.io/api/platform-browser/DomSanitizer#bypassSecurityTrustStyle - Marian07
3个回答

329

您遇到的这种行为是正常的。添加到innerHTML中的样式类被忽略,因为默认情况下封装是Emulated。这意味着Angular防止样式在组件内部和外部拦截。

您应该在组件中更改封装方式为None。这样,您就可以在任何地方定义类:在styles中或在单独的.css.scss.less样式表中(没有关系),Angular会自动将它们添加到DOM中。

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'example',
  styles: ['.demo {background-color: blue}'],
  template: '<div [innerHTML]="someHtmlCode"></div>',
  encapsulation: ViewEncapsulation.None,
})
export class Example {
  private someHtmlCode = '';

  constructor() {
    this.someHtmlCode = '<div class="demo"><b>This is my HTML.</b></div>';
  }
}

27
如果我只传递样式而没有类,它将无法正常工作。 - Chatra
4
您可能想查看这个 - DongBin Kim
10
ViewEncapsulation 是 Angular 核心库的一部分: import { ViewEncapsulation } from '@angular/core'; - Wiil
3
请确保从 @angular/core 导入 ViewEncapsulation,而不是从 @angular/compiler/src/core。否则,你将遇到一个神秘的错误 - “Cannot find module 'tslib'”! - Alphonso
17
值得注意的是,将ViewEncapsulation更改为None可能会产生相当深远的影响。这将全局应用您的样式 - 因此,如果您将div标记设置为具有背景颜色之类的内容,则所有应用中的div都将更改为具有该背景颜色。除非你绝对必须这样做,否则我建议你避免更改ViewEncapsulation。 - Jason Long
显示剩余10条评论

47

1
这是正确的答案,顺便说一下,我正在从Google API Gmail消息中提取HTML内容,其中包含内联样式,无法避免。使用这个解决方案,我实际上成功地显示了电子邮件的内容,就像Gmail显示它们一样,但愿我能给你+200,挽救了我的一天。 - WtFudgE
1
这不是@WtFudgE。一件事是注入HTML,是的,你需要/应该使用管道进行清理,另一件事是,一旦代码通过[innerHTML]注入,就有能力通过组件样式表进行样式设置。但你不能这样做——这是Angular多年前假定的一个错误,并没有得到妥善处理。所以...要对其进行样式设置,你需要通过encapsulation: ViewEncapsulation.None取消组件的封装。 - Pedro Ferreira
17
谢谢。我使用Quill编辑器创建的innerHTML代码时遇到了类似的问题。禁用ViewEncapsulation对style等所有属性都不起作用,因此您可以使用以下代码:<div [innerHTML]="sanitizer.bypassSecurityTrustHtml(yourObject.note)"></div>并将其添加到构造函数中:public sanitizer: DomSanitizer当然要注意XSS攻击! - René Preisler
我无法让这个方法识别 CSS 变量,例如 var(--blue) - cs_pupil
@RenéPreisler 谢谢,这对我有用。我在我的管理界面中使用Vue2-editor,在我的Angular应用程序中添加这个帮助我添加颜色,因为它是一个样式属性。 - Fabian
虽然这个链接可能回答了问题,但最好在这里包含答案的关键部分,并提供链接作为参考。仅有链接的答案如果链接页面发生变化可能会变得无效。- 来自审查 - undefined

-3

我将样式放入了一个类中,而不是使用内联样式。

不确定是否对您来说使用class是个选项,但这里有一个 Plunker demo

HTML:

this.someHtmlCode = '<div class="demo"><b>This is my HTML.</b></div>'

在全局根CSS文件中定义类demo,通常称为styles.scss

CSS:

.demo{
    background-color: blue;
}

它没有起作用,如果我的演示CSS在less文件中是否有任何区别? - Chatra
如果CSS在全局styles.css文件中,则此方法有效,但不适用于非全局CSS文件。如果有人能够解释其中的区别将会很有帮助,但与此同时,我想发表一条评论提醒其他人,让他们知道使其正常工作取决于这些细节。 - Mickey Segal
1
my-angular-component.html 包含 <div class="my-static-div" [innerHTML]="<div class='my-dynamic-div'>" (click)="handleStaticClick($event)" ... 然后在 my-angular-component.css 中使用 .my-static-div ::ng-deep .my-dynamic-div { color: blue; },在 my-angular-component.ts 中使用 public handleStaticClick(event) { if (event.srcElement.classList.contains('my-dynamic-div')) { this.handleDynamicClick(); }} - BeatriceThalo
3
我通过在类名前面放置选择器::ng-deep解决了我的问题。 - user3466681
实际上,我通过这种方式解决了我的问题。我在我的 style.scss 中定义了一个类 .mono { font-family: monospace !important; },然后像往常一样使用它:<h2 class="mono">Title</h2> - Martinocom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接