tooltip - 在 Angular 中使用自定义组件作为工具提示
问题描述
是否可以在 Angular 8 中使用自定义组件作为工具提示?
如果不直接设置 mat-tooltip 样式,我想知道是否可以在使用指令时使用自定义组件显示为工具提示。就像“显示工具提示时,显示我的组件”。
可以做到吗?
解决方案
是的,您可以创建自定义工具提示指令。
工具提示.directive.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;
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) // Here is your text
);
this.renderer.appendChild(document.body, this.tooltip);
this.renderer.addClass(this.tooltip, 'ng-tooltip');
this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
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();
const tooltipPos = this.tooltip.getBoundingClientRect();
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`);
}
}
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="tooltip-example">
<div tooltip="left description" placement="left" delay="500">tootip on left</div>
<div tooltip="top description" placement="top" delay="500">tootip on top</div>
<div tooltip="bottom description" placement="bottom" delay="500">tootip on bottom</div>
<div tooltip="right description" placement="right" delay="500">tootip on right</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 {}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TooltipDirective } from './tooltip.directive';
@NgModule({
declarations: [
AppComponent,
TooltipDirective
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
推荐阅读
- vb.net - 如何过滤包含列数据库中指定的所有单词的记录
- python - 如何利用字典计算数据框中的多个平均值
- javascript - 使用 switch case 和过滤/查找/循环对象数组来过滤并找到正确的对象以更新 JavaScript
- python - Python3如何从列表中检索列表
- shell - 在多个目录中执行`make`
- linux - 清漆 ESI 缓存 - 远程 url 返回 404
- reactjs - 在反应中将一些值从一页传递到另一页
- postgresql - Postgres lo_import 从其他表文本数据导入大对象
- javascript - JavaScript 编译器错误 - Google 跟踪代码管理器
- javascript - Wordpress 新页面和帖子未向公共用户显示 (IIS 8)