Angular自定義指令Tooltip的方法實(shí)例
Yeah,關(guān)注我的讀者應(yīng)該知道,上一篇文章了解 Angular 開發(fā)的內(nèi)容,我們已經(jīng)概覽了 Angular 的相關(guān)內(nèi)容。在自定義指令的部分,我們已經(jīng)能夠?qū)崿F(xiàn)編寫,但是,在實(shí)際場景中,我們還需要標(biāo)準(zhǔn)化的管理。
Angular 是 Angular.js 的升版
So,本文,我們就以 Tooltip 來講解下自定義指令的內(nèi)容。
線上效果圖,如下:

目錄結(jié)構(gòu)
在上一篇文章的實(shí)現(xiàn)的代碼項目基礎(chǔ)上,執(zhí)行命令行:
# 進(jìn)入 directives 文件夾 $ cd directives # 創(chuàng)建 tooltip 文件夾 $ mkdir tooltip # 進(jìn)入 tooltip 文件夾 $ cd tooltip # 創(chuàng)建 tooltip 組件 $ ng generate component tooltip # 創(chuàng)建 tooltip 指令 $ ng generate directive tooltip
執(zhí)行完上面的命令行之后,你會得到 app/directive/tooltip 的文件目錄結(jié)構(gòu)如下:
tooltip
├── tooltip // tooltip 組件
│ ├── user-list.component.html // 頁面骨架
│ ├── user-list.component.scss // 頁面獨(dú)有樣式
│ ├── user-list.component.spec.ts // 測試文件
│ └── user-list.component.ts // javascript 文件
├── tooltip.directive.spec.ts // 測試文件
└── tooltip.directive.ts // 指令文件
嗯,這里我將組件放在 tooltip 的同級,主要是方便管理。當(dāng)然,這個因人而異,你可以放在公共組件 components 文件夾內(nèi)。
編寫 tooltip 組件
在 html 文件中,有:
<div class="caret"></div>
<div class="tooltip-content">{{data.content}}</div>在樣式文件 .scss 中,有:
$black: #000000;
$white: #ffffff;
$caret-size: 6px;
$tooltip-bg: transparentize($black, 0.25); // transparentize 是 sass 的語法
$grid-gutter-width: 30px;
$body-bg-color: $white;
$app-anim-time: 200ms;
$app-anim-curve: ease-out;
$std-border-radius: 5px;
$zindex-max: 100;
// :host 偽類選擇器,給組件元素本身設(shè)置樣式
:host {
position: fixed;
padding: $grid-gutter-width/3 $grid-gutter-width/2;
background-color: $tooltip-bg;
color: $body-bg-color;
opacity: 0;
transition: all $app-anim-time $app-anim-curve;
text-align: center;
border-radius: $std-border-radius;
z-index: $zindex-max;
}
.caret { // 脫字符
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $tooltip-bg;
position: absolute;
top: -$caret-size;
left: 50%;
margin-left: -$caret-size/2;
border-bottom-color: $tooltip-bg;
}嗯~,css 是一個神奇的東西,之后會安排一篇文章來講解下 sass 相關(guān)的內(nèi)容...
然后,在 javascript 文件 tooltip.component.ts 內(nèi)容如下:
import {
Component,
ElementRef, // 元素指向
HostBinding,
OnDestroy,
OnInit
} from '@angular/core';
@Component({
selector: 'app-tooltip', // 標(biāo)識符,表明我這個組件叫做啥,這里是 app-tooltip
templateUrl: './tooltip.component.html', // 本組件的骨架
styleUrls: ['./tooltip.component.scss'] // 本組件的私有樣式
})
export class TooltipComponent implements OnInit {
public data: any; // 在 directive 上賦值
private displayTimeOut:any;
// 組件本身 host 綁定相關(guān)的裝飾器
@HostBinding('style.top') hostStyleTop!: string;
@HostBinding('style.left') hostStyleLeft!: string;
@HostBinding('style.opacity') hostStyleOpacity!: string;
constructor(
private elementRef: ElementRef
) { }
ngOnInit(): void {
this.hostStyleTop = this.data.elementPosition.bottom + 'px';
if(this.displayTimeOut) {
clearTimeout(this.displayTimeOut)
}
this.displayTimeOut = setTimeout((_: any) => {
// 這里計算 tooltip 距離左側(cè)的距離,這里計算公式是:tooltip.left + 目標(biāo)元素的.width - (tooltip.width/2)
this.hostStyleLeft = this.data.elementPosition.left + this.data.element.clientWidth / 2 - this.elementRef.nativeElement.clientWidth / 2 + 'px'
this.hostStyleOpacity = '1';
this.hostStyleTop = this.data.elementPosition.bottom + 10 + 'px'
}, 500)
}
// 組件銷毀
ngOnDestroy() {
// 組件銷毀后,清除定時器,防止內(nèi)存泄露
if(this.displayTimeOut) {
clearTimeout(this.displayTimeOut)
}
}
}編寫 tooltip 指令
這是本文的重點(diǎn),具體的說明,我在代碼上標(biāo)注出來~
相關(guān)的文件 tooltip.directive.ts 內(nèi)容如下:
import {
ApplicationRef, // 全局性調(diào)用檢測
ComponentFactoryResolver, // 創(chuàng)建組件對象
ComponentRef, // 組件實(shí)例的關(guān)聯(lián)和指引,指向 ComponentFactory 創(chuàng)建的元素
Directive, ElementRef,
EmbeddedViewRef, // EmbeddedViewRef 繼承于 ViewRef,用于表示模板元素中定義的 UI 元素。
HostListener, // DOM 事件監(jiān)聽
Injector, // 依賴注入
Input
} from '@angular/core';
import { TooltipComponent } from './tooltip/tooltip.component';
@Directive({
selector: '[appTooltip]'
})
export class TooltipDirective {
@Input("appTooltip") appTooltip!: string;
private componentRef!: ComponentRef<TooltipComponent>;
// 獲取目標(biāo)元素的相關(guān)位置,比如 left, right, top, bottom
get elementPosition() {
return this.elementRef.nativeElement.getBoundingClientRect();
}
constructor(
protected elementRef: ElementRef,
protected appRef: ApplicationRef,
protected componentFactoryResolver: ComponentFactoryResolver,
protected injector: Injector
) { }
// 創(chuàng)建 tooltip
protected createTooltip() {
this.componentRef = this.componentFactoryResolver
.resolveComponentFactory(TooltipComponent) // 綁定 tooltip 組件
.create(this.injector);
this.componentRef.instance.data = { // 綁定 data 數(shù)據(jù)
content: this.appTooltip,
element: this.elementRef.nativeElement,
elementPosition: this.elementPosition
}
this.appRef.attachView(this.componentRef.hostView); // 添加視圖
const domElem = (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
document.body.appendChild(domElem);
}
// 刪除 tooltip
protected destroyTooltip() {
if(this.componentRef) {
this.appRef.detachView(this.componentRef.hostView); // 移除視圖
this.componentRef.destroy();
}
}
// 監(jiān)聽鼠標(biāo)移入
@HostListener('mouseover')
OnEnter() {
this.createTooltip();
}
// 監(jiān)聽鼠標(biāo)移出
@HostListener('mouseout')
OnOut() {
this.destroyTooltip();
}
}到這里,已經(jīng)完成了 99% 的功能了,下面我們在頁面上調(diào)用即可。
頁面上調(diào)用
我們在 user-list.component.html 上添加下面的內(nèi)容:
<p style="margin-top: 100px;">
<!-- [appTooltip]="'Hello Jimmy'" 是重點(diǎn) -->
<span
[appTooltip]="'Hello Jimmy'"
style="margin-left: 200px; width: 160px; text-align: center; padding: 20px 0; display: inline-block; border: 1px solid #999;"
>Jimmy</span>
</p>TooltipDirective 這個指令我們已經(jīng)在 app.module.ts 上進(jìn)行聲明,我們直接調(diào)用即可。目前的效果如下:

我們實(shí)現(xiàn)的 tooltip 是底部居中展示,也就是我們平常使用框架,比如 angular ant design 中 tooltip 的 bottom 屬性。對于其他屬性,讀者感興趣的話,可以進(jìn)行擴(kuò)展。
至此,我們可以很好的維護(hù)自己編寫的指令文件了。
總結(jié)
到此這篇關(guān)于Angular自定義指令Tooltip的文章就介紹到這了,更多相關(guān)Angular自定義指令Tooltip內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
AnjularJS中$scope和$rootScope的區(qū)別小結(jié)
這篇文章給大家整理了關(guān)于AnjularJS中$scope和$rootScope的區(qū)別,文中運(yùn)用實(shí)例代碼介紹的很詳細(xì),有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-09-09
詳解AngularJS1.x學(xué)習(xí)directive 中‘& ’‘=’ ‘@’符號的區(qū)別使用
這篇文章主要介紹了詳解AngularJS1.x學(xué)習(xí)directive 中‘& ’‘=’ ‘@’符號的區(qū)別使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-08-08
angularjs的select使用及默認(rèn)選中設(shè)置
本篇文章主要介紹了angularjs的select使用及默認(rèn)選中設(shè)置,非常具有實(shí)用價值,需要的朋友可以參考下2017-04-04
angular 實(shí)時監(jiān)聽input框value值的變化觸發(fā)函數(shù)方法
今天小編就為大家分享一篇angular 實(shí)時監(jiān)聽input框value值的變化觸發(fā)函數(shù)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
使用Angular CLI生成 Angular 5項目教程詳解
這篇文章主要介紹了使用Angular CLI生成 Angular 5項目的教程詳解 ,需要的朋友可以參考下2018-03-03
AngularJS實(shí)現(xiàn)動態(tài)添加Option的方法
這篇文章主要介紹了AngularJS實(shí)現(xiàn)動態(tài)添加Option的方法,涉及AngularJS事件響應(yīng)及頁面元素動態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-05-05
AngularJS中的指令實(shí)踐開發(fā)指南(二)
這篇文章主要介紹了AngularJS中的指令實(shí)踐指南(二)的相關(guān)資料,需要的朋友可以參考下2016-03-03

