import { Directive, ElementRef, Renderer2, HostListener, NgZone, OnDestroy, Input, AfterViewInit } from '@angular/core'; @Directive({ selector: '[f-input-tips]' }) export class FInputTipsDirective implements OnDestroy, AfterViewInit { private cloneEl = null; private tipsText = ""; mouseEnterListener: any; // 如果是不是用默认的Title,此属性相关的功能可以移除 mouseLeaveListener: any; private _enableTips = true; @Input('f-input-tips') set enableTips(value) { if (this._enableTips !== value) { this._enableTips = value; this.changeEventBind(); } } get enableTips() { return this._enableTips; } constructor(private el: ElementRef, public ngzone: NgZone, private render: Renderer2) { } private createCloneEl() { if (!this.el.nativeElement) { return; } const global = { cloneCSSProperties: [ 'line-height', 'letter-spacing', 'font-size', 'font-family', 'font-style', 'font-weight', 'border', 'padding', 'height' ] }; const el$ = window.getComputedStyle(this.el.nativeElement); this.cloneEl = this.render.createElement('span'); this.cloneEl['innerText'] = el$['value']; global.cloneCSSProperties.forEach((item, index) => { this.cloneEl.style[item] = el$.getPropertyValue(item); }); this.render.addClass(this.cloneEl, 'f-dir-hidden-el'); this.render.appendChild(document.body, this.cloneEl); } ngAfterViewInit() { this.changeEventBind(); } changeEventBind() { if (this.enableTips) { this.ngzone.runOutsideAngular(() => { this.mouseEnterListener = this.onMouseEnterHandler.bind(this); this.el.nativeElement.addEventListener('mouseenter', this.mouseEnterListener); this.mouseLeaveListener = this.onMouseLeaveHandler.bind(this); this.el.nativeElement.addEventListener('mouseleave', this.mouseLeaveListener); }); } else { if (this.mouseEnterListener) { this.el.nativeElement.removeEventListener('mouseenter', this.mouseEnterListener); this.mouseEnterListener = null; this.el.nativeElement.removeEventListener('mouseleave', this.mouseLeaveListener); this.mouseLeaveListener = null; } } } ngOnDestroy() { if (this.cloneEl) { this.render.removeChild(document.body, this.cloneEl); } } onMouseEnterHandler() { this.changeTitle(); } onMouseLeaveHandler() { // 移除提示 this.render.setAttribute(this.el.nativeElement, 'title', ''); } private changeTitle() { if (!this.cloneEl) { this.createCloneEl(); } this.tipsText = this.el.nativeElement['value']; this.cloneEl['innerText'] = this.tipsText; this.ngzone.runOutsideAngular(() => { setTimeout(() => { if (this.cloneEl.getBoundingClientRect().width > this.el.nativeElement.getBoundingClientRect().width) { this.render.setAttribute(this.el.nativeElement, "title", this.tipsText); } else { this.onMouseLeaveHandler(); } }, 0); }); } }