#angular #angular-directive
Вопрос:
Я использую директиву Angular, позволяющую отображать всплывающую подсказку с событиями mouseEnter и mouseLeave.
все работает нормально, за исключением того, что при прокрутке всплывающая подсказка не исчезает и остается отображаемой.
Я попытался использовать прослушиватель @Hostlistener, но он не работает на мобильных устройствах.
@HostListener('document:wheel', ['$event.target']) public onWheel() { if (this.tooltip) { this.renderer.removeClass(this.tooltip, 'ng-tooltip-show'); } }
У вас есть решение ?
https://stackblitz.com/edit/angular-tooltip-directive-uprxbd?file=app/tooltip.directive.ts
приложение.компонент.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="tooltip-example" style="margin-top:100px">
<div [tooltip]="displayStatut()" placement="top" delay="500">tootip on top</div>
</div>
`,
styles: [`
.tooltip-example {
text-align: center;
padding: 0 50px;
}
.tooltip-example [tooltip] {
display: inline-block;
margin: 50px 20px;
width: 180px;
height: 50px;
border: 1px solid gray;
border-radius: 5px;
line-height: 50px;
text-align: center;
}
.ng-tooltip {
position: absolute;
max-width: 150px;
font-size: 14px;
text-align: center;
color: #f8f8f2;
padding: 3px 8px;
background: #282a36;
border-radius: 4px;
z-index: 1000;
opacity: 0;
}
.ng-tooltip:after {
content: "";
position: absolute;
border-style: solid;
}
.ng-tooltip-top:after {
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-color: black transparent transparent transparent;
}
.ng-tooltip-bottom:after {
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-color: transparent transparent black transparent;
}
.ng-tooltip-left:after {
top: 50%;
left: 100%;
margin-top: -5px;
border-width: 5px;
border-color: transparent transparent transparent black;
}
.ng-tooltip-right:after {
top: 50%;
right: 100%;
margin-top: -5px;
border-width: 5px;
border-color: transparent black transparent transparent;
}
.ng-tooltip-show {
opacity: 1;
}
`]
})
export class AppComponent {
public displayStatut() {
let content;
content = "<ul style='margin-bottom:10px;text-align: left'><li>Test</li></ul>";
return content;
}
}
подсказка.директива.ts
import { Directive, Input, ElementRef, HostListener, Renderer2 } from '@angular/core'; @Directive({ selector: '[tooltip]' }) export class TooltipDirective { @Input('tooltip') tooltipTitle: string; @Input() placement: string; @Input() delay: string; tooltip: HTMLElement; tooltip offset = 10; constructor(private el: ElementRef, private renderer: Renderer2) { } @HostListener('mouseenter') onMouseEnter() { if (!this.tooltip) { this.show(); } } @HostListener('mouseleave') onMouseLeave() { if (this.tooltip) { this.hide(); } } show() { this.create(); this.setPosition(); this.renderer.addClass(this.tooltip, 'ng-tooltip-show'); } hide() { this.renderer.removeClass(this.tooltip, 'ng-tooltip-show'); window.setTimeout(() => { this.renderer.removeChild(document.body, this.tooltip); this.tooltip = null; }, this.delay); } create() { this.tooltip = this.renderer.createElement('span'); this.renderer.appendChild( this.tooltip, this.renderer.createText(this.tooltipTitle) // textNode ); this.renderer.appendChild(document.body, this.tooltip); // this.renderer.appendChild(this.el.nativeElement, this.tooltip); this.renderer.addClass(this.tooltip, 'ng-tooltip'); this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`); // delay this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity ${this.delay}ms`); this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity ${this.delay}ms`); this.renderer.setStyle(this.tooltip, '-o-transition', `opacity ${this.delay}ms`); this.renderer.setStyle(this.tooltip, 'transition', `opacity ${this.delay}ms`); } setPosition() { const hostPos = this.el.nativeElement.getBoundingClientRect(); // tooltip const tooltipPos = this.tooltip.getBoundingClientRect(); // window scroll top // getBoundingClientRect viewport. const scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; let top, left; if (this.placement === 'top') { top = hostPos.top - tooltipPos.height - this.offset; left = hostPos.left (hostPos.width - tooltipPos.width) / 2; } if (this.placement === 'bottom') { top = hostPos.bottom this.offset; left = hostPos.left (hostPos.width - tooltipPos.width) / 2; } if (this.placement === 'left') { top = hostPos.top (hostPos.height - tooltipPos.height) / 2; left = hostPos.left - tooltipPos.width - this.offset; } if (this.placement === 'right') { top = hostPos.top (hostPos.height - tooltipPos.height) / 2; left = hostPos.right this.offset; } this.renderer.setStyle(this.tooltip, 'top', `${top scrollPos}px`); this.renderer.setStyle(this.tooltip, 'left', `${left}px`); } }
Ответ №1:
Вы пробовали использовать CSS ? Например
.ng-tooltip {
overflow: hidden; /* Hide scrollbars */
}