mouseenter / mouseleave с @HostListener

Мерцание убивает меня, и после прочтения всех связанных с jQuery потоков и mdn я все еще не могу понять это.

Итак, у меня есть этот @Directive для показа всплывающей подсказки, и вот как я связываю его с элементами:

  @HostListener('mouseenter', ['$event']) onEnter( e: MouseEvent ) {
    this.showTooltip(e);
  }

  @HostListener('mouseleave', ['$event']) onLeave( e: MouseEvent ) {
    this.hideTooltip(e);
  }

  @HostListener('click', ['$event']) onClick( e: MouseEvent ) {
    this.hideTooltip(e);
  }

  constructor(
    private el: ElementRef,
    private renderer: Renderer2,
    private coordsService: CoordsService,
    @Inject(DOCUMENT) doc
  ) {
    this.docBody = doc.body;
  }

  public ngAfterViewInit(): void {
    this.tooltipContainer = this.renderer.createElement('div');
    this.renderer.addClass( this.tooltipContainer, 'tooltip--tip');
    this.renderer.addClass( this.tooltipContainer, 'tooltip--pos_' + this.position);
  }

  public showTooltip( e: MouseEvent ): void {

    if ( this.tooltip !== null ) {

      // text 
      this.selectedTooltip = this.renderer.createText( this.tooltip );

      // append to body
      this.renderer.appendChild( this.tooltipContainer, this.selectedTooltip);
      this.renderer.appendChild( this.docBody, this.tooltipContainer );

      // target element
      const target: HTMLElement = <HTMLElement>e.target;
      const bbox: ClientRect = target.getBoundingClientRect();

      // the array holds the pixel position of the property; should sync with top:left
      let coords: ElementCoords = this.coordsService.setPositionCoords(bbox, this.position, this.tooltipContainer, { left: -6 } );

      // write position
      this.renderer.setStyle( this.tooltipContainer, 'top', coords.top+'px' );
      this.renderer.setStyle( this.tooltipContainer, 'left', coords.left+'px' );
    }

  }

  public hideTooltip( e: MouseEvent ): void {
    if ( this.selectedTooltip ) {
      this.renderer.removeChild ( this.tooltipContainer, this.selectedTooltip);
      this.renderer.removeChild( this.docBody, this.tooltipContainer );
      this.selectedTooltip = null;
    }
  }

каждый <span> который имеет текст в нем мерцает. Каждый селектор с SVG мерцает... Есть идеи?

PS. как-то el: ElementRef не используется, хотя я сделал это по какой-то причине. Попробовал сопоставить ссылку на него - все равно не повезло.

1 ответ

Решение

Ваша подсказкаКонтейнер вызывает mouseleave потому что это над элементом. Если вы не против, вы не можете ничего щелкнуть / выбрать там. Установите в своем CSS pointer-events: none к подсказкеКонтейнер.

Вы вводите элемент с помощью директивы (mouseenter), контейнер всплывающей подсказки проходит над этим элементом. Теперь у подсказки есть курсор над ней. Ага! Это вызывает (mouseleave) из элемента с директивой, поэтому подсказка исчезает. Но эй, не директива снова имеет курсор... (мышонок)!... но эй! всплывающая подсказка снова под курсором... (указатель мыши)... и т. д.:)

С помощью событий указателя вы убедитесь, что наложенный элемент не получает никаких четных событий, и они запускаются для элемента под ним. Однако вы также можете попытаться сделать так, чтобы всплывающая подсказка не перекрывала элемент, но решать вам

Другие вопросы по тегам