我从HTTP调用中获取大量HTML代码。我将HTML块放在一个变量中并使用[innerHTML]将其插入到我的页面中,但我无法设置插入的HTML块的样式。有没有人有任何建议我怎么做到这一点?
lme4
我想要设置样式的HTML是变量" calendar"中包含的块。
答案 0 :(得分:257)
更新2 ::slotted
::slotted
,并且可以与`ViewEncapsulation.ShadowDom
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
更新1 :: ng-deep
/deep/
已被弃用,取而代之的是::ng-deep
。
::ng-deep
也已标记为已弃用,但尚无可用的替代品。
当所有浏览器都正确支持ViewEncapsulation.Native
并支持横向DOM边界的样式时,::ng-deep
可能会停止使用。
<强>原始强>
Angular将各种CSS类添加到它添加到DOM的HTML中,以模拟shadow DOM CSS封装,以防止组件内外流失的样式。 Angular还会重写您添加的CSS以匹配这些添加的类。对于使用[innerHTML]
添加的HTML,不会添加这些类,并且重写的CSS不匹配。
作为解决方法尝试
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector {
background-color: blue;
}
index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
background-color: green;
}
>>>
(等效/deep/
但/deep/
在SASS方面效果更好),::shadow
在2.0.0-beta.10中添加。它们类似于shadow DOM CSS组合器(不推荐使用),只能与encapsulation: ViewEncapsulation.Emulated
一起使用,这是Angular2中的默认设置。它们可能也与ViewEncapsulation.None
一起使用,但之后只会被忽略,因为它们不是必需的。
在支持跨组件样式的更高级功能之前,这些组合器只是一种中间解决方案。
另一种方法是使用
@Component({
...
encapsulation: ViewEncapsulation.None,
})
阻止CSS的所有组件(取决于您添加CSS的位置以及要设置样式的HTML的位置 - 可能是应用程序中的所有组件)
<强>更新强>
答案 1 :(得分:4)
您需要遵循的简单解决方案是
transformYourHtml(htmlTextWithStyle) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
答案 2 :(得分:2)
我们经常以[innerHTML]="content.title"
的身份从CMS中提取内容。我们将必要的类放置在应用程序的根styles.scss
文件中,而不是组件的scss文件中。我们的CMS特意去除了内联样式,因此我们必须准备好准备好供作者在其内容中使用的类。请记住,在模板中使用{{content.title}}
不会从内容中呈现html。
答案 3 :(得分:0)
如果您试图在Angular组件中为动态添加的HTML元素设置样式,这可能会有所帮助:
// inside component class...
constructor(private hostRef: ElementRef) { }
getContentAttr(): string {
const attrs = this.hostRef.nativeElement.attributes
for (let i = 0, l = attrs.length; i < l; i++) {
if (attrs[i].name.startsWith('_nghost-c')) {
return `_ngcontent-c${attrs[i].name.substring(9)}`
}
}
}
ngAfterViewInit() {
// dynamically add HTML element
dynamicallyAddedHtmlElement.setAttribute(this.getContentAttr(), '')
}
我的猜测是,不能保证此属性的约定在Angular的两个版本之间是稳定的,因此在升级到新版本的Angular时,此解决方案可能会遇到问题(尽管更新此解决方案可能会在这种情况下是微不足道的。
答案 4 :(得分:0)
如果您将sass用作样式预处理器,则可以通过以下方式切换回本机Sass编译器以获取开发依赖:
npm install node-sass --save-dev
以便您可以继续使用/ deep /进行开发。
答案 5 :(得分:0)
GünterZöchbauer推荐的版本效果很好,但我还有一个补充。就我而言,我有一个未设置样式的html元素,我不知道如何设置它的样式。因此,我设计了一个管道来为其添加样式。
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Pipe({
name: 'StyleClass'
})
export class StyleClassPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(html: any, styleSelector: any, styleValue: any): SafeHtml {
const style = ` style = "${styleSelector}: ${styleValue};"`;
const indexPosition = html.indexOf('>');
const newHtml = [html.slice(0, indexPosition), style, html.slice(indexPosition)].join('');
return this.sanitizer.bypassSecurityTrustHtml(newHtml);
}
}
然后您可以将样式添加到任何html元素中,如下所示:
<span [innerhtml]="Variable | StyleClass: 'margin': '0'"> </span>
使用:
Variable = '<p> Test </p>'
答案 6 :(得分:0)
对于任何想要将某种样式应用于 innerHTML 的人:
您可以使用 CSS 样式连接 HTML 字符串,如下所示:
return this.sanitizer.bypassSecurityTrustHtml(value+='<style type="text/css">.image img { width: 100% }</style>');
这个 value
来自 transform(value, ...args)
答案 7 :(得分:0)
我最初采用 this.sanitizer.bypassSecurityTrustHtml()
路线,并将封装设置为 ViewEncapsulation.NONE
,但有两个问题:
ViewEncapsulation.NONE
导致我的组件出现其他样式问题这对我有用(无需更改任何其他内容): InsertAdjacentHTML
模板:
<div id=template></div>
代码:
ngOnInit() {
const el = document.getElementById('template');
el.insertAdjacentHTML('afterbegin', `<span style="color: var(--blue)">hello</span>`);
}
免责声明:就我而言,我是从配置文件中解析 html 的。您不想使用用户输入的 html 走这条路线。
答案 8 :(得分:0)
最简单直接的方法是使用位于 angular 项目 src 文件夹中的全局样式文件。
假设组件选择器是:app-my-component
在 app-my-component 模板中为承载 innerHtml 内容的元素添加一个类:
<div class="innerhtml-class" [innerHTML]="variable.innerHtml"></div>
添加到全局样式文件:
app-my-component {
.innerhtml-class {
declaration goes here
}
}
答案 9 :(得分:0)
使用以下方法允许 innerhtml
中的 CSS 样式。
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
.
.
.
.
html: SafeHtml;
constructor(protected _sanitizer: DomSanitizer) {
this.html = this._sanitizer.bypassSecurityTrustHtml(`
<html>
<head></head>
<body>
<div style="display:flex; color: blue;">
<div>
<h1>Hello World..!!!!!</h1>
</div>
</div>
</body>
</html>`);
}
示例代码 stackblitz
或者使用下面的方法直接在HTML中编写。 https://gist.github.com/klihelp/4dcac910124409fa7bd20f230818c8d1
答案 10 :(得分:0)
如果您的动态样式有限,则使用 inline CSS variables 是一种替代解决方案。
即
// file.ts
someVarWithHtml = 'Hello <span class="dynamic">World</span>';
// file.ng.html
<div [style]="'--my-var: ' + value"
[innerHTML]="someVarWithHtml"></div>
// style.css
.dynamic {
background: var(--my-var);
}