Search code examples
angularmouseeventinnerhtml

Multiple mouse events not working when binding innerHTML


I'm trying to auto-generate a complex/interactive SVG image in angular, but it seems like there is a problem in the event bindings.

I've tried with [click] event only and it works fine and the event is triggered. also, [mouseout] event works fine on its own or with [click] event. but when I add [mouseenter] or [mouseover] no other events are triggered. I tried to leave only one event directly bonded to the element and listen to [mouseout] and [click] using @HostListener Decorator but it doesn't work either!

I think the [innerHTML] has to do something about this but it's very important and I couldn't remove it. simply I don't know what are the sub-elements of this group, they are dynamically generated or uploaded by the user as a simple SVG generated by adobe illustrator so I'm using a js to XML converter to generate the internal objects of the group.

  <svg>
    <g id="group">
      <g *ngFor="let object of array"
        (mouseenter)="hoverStarted($event, object)"
        (mouseout)="hoverEnded($event, object)"
        (click)="objectClick(object)"
        [innerHTML]="getObjectInternalSvgString(object)"
        >
      </g>
    </g>
  </svg>

I expect that all of the mouse events [mouseenter, mouseout, click] to be triggered, but only [mouseenter] is being triggered. and when I remove [mouseenter] both [mouseout] and [click] work flawlessly.


Solution

  • I figured out a solution that works great!

    first, I removed the innerHTML binding from the group and added a TemplateReference identifier.

    then in the .ts file I added ViewChildren with a QueryList for this identifier, and only injecting the innerHTML once after view init.

      <svg>
        <g id="group">
          <g *ngFor="let object of array"
            (mouseenter)="hoverStarted($event, object)"
            (mouseout)="hoverEnded($event, object)"
            (click)="objectClick(object)"
            #groups
            >
          </g>
        </g>
      </svg>
    
    @ViewChildren('groups') objectGroups: QueryList<ElementRef>;
    ngAfterViewInit() {
       const objectArray = this.objectGroups.toArray();
       for ( const index in objectArray ) {
          objectArray[index].nativeElement.innerHTML = this.getObjectInternalSvgStringByIndex(index)
       }
    }
    

    and now all the mouse events works flawlessly.