1

I am facing a problem where I need to display dynamic HTML content that includes a dynamic background-color value, as part of a string that contains style tags and an id. Here's an example:

this is <mark id="12345" style="background-color: red">my marked</mark> text? 

I am using the innerHTML property to display the content in my Angular app, but I am having issues with applying styles and adding a click listener in the same time.

Here's my code:

HTML

<div [innerHTML]="myString"></div>

TS

  ngAfterViewInit(): void {
    setTimeout(() => {
      const markTags = this.description.nativeElement.querySelectorAll('mark');
      markTags.forEach((tag: HTMLElement) => {
        tag.addEventListener('click', (event) => {
        });
      });
    }, 100);
  }

In this case the click listener works, but the style is not applied.

When I use bypassSecurityTrustHtml to sanitize the HTML content, the styles do apply, but the click listener does not work.

   private readonly _sanitizer: DomSanitizer,  
   return this._sanitizer.bypassSecurityTrustHtml(TASK.description);

How can i apply both the click listeners and the styles to this HTML content?

I would like also to mention that the app is inside a closed network so the security risks are minor.

Anna
  • 131
  • 2
  • 11

2 Answers2

1

Its simpler. Angular has some events directives built in, one of them is (click)="isClicked($event)" look this doc.

And about styles, you can look for this post.

Riheldo Melo
  • 114
  • 5
1

I modified the html like this:

<div #myDiv [innerHTML]="descr"></div>

and added some variables:

description =
    'this is <mark id="12345" style="background-color: red">my marked</mark> text?';
  descr: SafeHtml;
  @ViewChild('myDiv', { static: true }) myDiv: ElementRef;

and modified the methods like this:

constructor(private sanitizer: DomSanitizer) {}

  ngOnInit() {
    this.descr = this.sanitizer.bypassSecurityTrustHtml(this.description);
  }

  ngAfterViewInit() {
    const markTags = this.myDiv.nativeElement.querySelectorAll('mark');
    markTags.forEach((tag: HTMLElement) => {
      tag.addEventListener('click', (event) => {
        alert('mark clicked');
      });
    });
  }

Here is a functioning stacklbitz too: stackblitz

derstauner
  • 1,478
  • 2
  • 23
  • 44