Search code examples
angularangular11

Angular - Click Event on Images inside of [innerHTML]


I have an application where users can write notes and, in these notes, they can include an image. Sometimes these images are large, and I have CSS that makes them fit into a container.

I am trying to make a click event on any image that may show up in the notes where it will either enlarge the image to see it clearer or open the image in a new tab.

Since the HTML is not written directly in my application, and I get data from the database and display it, I cannot add (click)="doSomething()" on the image via HTML.

Users can right click on the image and choose to open it in a new tab. But I am trying to simplify that.

I have found approaches where I can add JS on load events to do action on any image on the page, but that is not what I am looking for. I only want to target any image generated in this component.

If needed, I can create a StackBlitz example, but I am hoping it is something simple that I am just missing.

Notes

Current HTML:

<div class="row" style="margin-top: 10px">
  <div class="col-md-12 note-container ql-editor">
    <div
      *ngIf="data.isEnabled"
      [innerHTML]="data.noteText | safeHtml"
    ></div>
  </div>
  <div class="col-md-12 note-container">
    <div *ngIf="!data.isEnabled">
      <i>This message has been deleted.</i>
    </div>
  </div>
</div>

Solution

  • Following the example in this answer. This is what worked out for us.

    Add (click) event to the same div (or element you are using) as the [innerHtml]

    <div class="row" style="margin-top: 10px">
      <div class="col-md-12 note-container ql-editor">
        <div
          *ngIf="data.isEnabled"
          (click)="onNoteClick($event)"
          [innerHTML]="data.noteText | safeHtml"
        ></div>
      </div>
      <div class="col-md-12 note-container">
        <div *ngIf="!data.isEnabled">
          <i>This message has been deleted.</i>
        </div>
      </div>
    </div>
    

    Then handle the click and check for the image. Currently, for this example I am only checking for base64 images since our rich text editor converts them to base64 when selecting from computer and we don't allow for code editing in the editor.

    onNoteClick(event) {
      const imgSrc = event.target.currentSrc;
      if (imgSrc && imgSrc.includes("data:image")) {
        let w = window.open();
        let img = new Image();
        img.src = imgSrc;
        const html =
          "<title>Image</title><style>body {margin: unset} img {max-width: 100%}</style>" +
          img.outerHTML;
        w.document.write(html);
      }
    }
    

    All other clicks outside of images in the innerHTML get ignored.