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) из элемента с директивой, поэтому подсказка исчезает. Но эй, не директива снова имеет курсор... (мышонок)!... но эй! всплывающая подсказка снова под курсором... (указатель мыши)... и т. д.:)
С помощью событий указателя вы убедитесь, что наложенный элемент не получает никаких четных событий, и они запускаются для элемента под ним. Однако вы также можете попытаться сделать так, чтобы всплывающая подсказка не перекрывала элемент, но решать вам