簡體   English   中英

阻止“innerHTML”中的樣式影響父級

[英]Stop styles in `innerHTML` from impacting parent

我創建了一個 HTML 電子郵件,它在我測試過的幾個電子郵件客戶端中正確顯示,但是當我在我的頁面上提供它的預覽時, innerHTML的嵌入樣式會影響父級。 必須可以避免這種情況,因為當我在 gmail 中查看電子郵件時,它可以正確顯示而不會更改 gmail 本身的樣式。

這是一些顯示問題的 HTML(但在 gmail 中顯示沒有副作用):

<!DOCTYPE HTML>
<html>
    <head>
        <style type="text/css">
            * { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; }
        </style>
    </head>
    <body>
        <pre style="white-space:pre-wrap;">Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
    </body>    
</html> 

我正在使用 Angular 4,所以我以這種方式將它包含在我的頁面中:

<div [innerHTML]="myHtml | safeHtml">
</div>

...而 safeHtml 只是繞過對我正在注入的 HTML 進行 Angular 檢查的管道:

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";

@Pipe({name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
  constructor(private sanitizer:DomSanitizer){}

  transform(html) {

    return this.sanitizer.bypassSecurityTrustHtml(html);

  }
}

它有效,因為它確實在 div 中顯示了 html,但樣式信息會更改頁面上的所有內容。 我明白了 - 我實際上是在我的嵌入式樣式中使用* ...但正如我所說,gmail 設法以某種方式“包含”它,因此它不會重新設置父元素的樣式。 我該如何實現?

理想情況下,我希望完全隔離樣式 - 就像我不希望父樣式受到子樣式的影響或子樣式受到父樣式的影響(這似乎是 gmail 的行為方式)。

更新

將 HTML 更改為以下內容使其適用於電子郵件,並包含 CSS,但無法嵌入到 Angular 中:

<!DOCTYPE HTML>
<html class="my-class">
    <head>
        <style type="text/css">
            .my-class * { 
                font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; 
                color: blue;
            }
            .my-class pre {
                white-space:pre-wrap;
            }
        </style>
    </head>
    <body>
        <pre>Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
    </body>    
</html>   

這是因為(似乎)當您將其嵌入到div時, htmlbody標簽被刪除了(這是有道理的)。 因此,只需在類中添加一個包含div的父級,它就可以正常工作 - 無論是嵌入還是在電子郵件中:

<!DOCTYPE HTML>
<html>
    <head>
        <style type="text/css">
            .my-class * { 
                font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; 
                color: blue;
            }
            .my-class pre {
                white-space:pre-wrap;
            }
        </style>
    </head>
    <body>
        <div class="my-class">
            <pre>Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
        </div>
    </body>    
</html> 

@petryuno1 建議的最佳方法是使用組件,因為它會將 CSS/樣式范圍僅限於該組件,但在基本級別上,您可以將類應用於<div [innerHTML]="myHtml | safeHtml"></div>如:

<div class="foo" [innerHTML]="myHtml | safeHtml"></div>

如果組件不可用,則將 css 修改為針對類的*

.foo * { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; }

無論對innerHTML進行了何種修改,該<div>上的class屬性都將保留。

希望這有幫助!

我發現使用 Angular 解決類似問題的另一個解決方案(必須在頁面中顯示電子郵件的 HTML)是創建一個新組件來顯示預覽並將封裝設置為 ShadowDom。

  @Component({
  selector: 'app-email-view',
  templateUrl: './email-view.component.html',
  styleUrls: ['./email-view.component.scss'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class EmailViewComponent implements OnInit {

  @Input()
  preview: any;

之后,我只需在[innerHtml]元素中插入preview變量。

ShadowDom 負責封裝 Style 並且不讓它影響其他組件。 有關更多信息,您可以在此處查看

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM