如何在 Angular 指令中添加 html 标签?
How to add html tags in an Angular directive?
我得到了一个工具提示指令,允许我在将鼠标悬停在元素上时显示工具提示。
但是我希望在工具提示中显示的文本能够集成 Html 标签。
但我遇到的问题是标签被认为是文本
是否有将 html 标签集成到工具提示标题中的解决方案?
代码如下:
app.component.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;
}
}
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;
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`); } }
https://stackblitz.com/edit/angular-tooltip-directive-fkawer
您使用已弃用的渲染器需要将 InnerHTML 设置为 nativeElement,例如
this.renderer.setElementProperty(el.nativeElement, 'innerHTML', this.tooltipTitle);
或者,如果您使用 Renderer2,则其
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.tooltipTitle);
如果工具提示内容来自外部,您还需要使用DomSanitizer
this.sanitizer.bypassSecurityTrustHtml(content)
我得到了一个工具提示指令,允许我在将鼠标悬停在元素上时显示工具提示。
但是我希望在工具提示中显示的文本能够集成 Html 标签。
但我遇到的问题是标签被认为是文本
是否有将 html 标签集成到工具提示标题中的解决方案?
代码如下:
app.component.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;
}
}
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; 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`); } }
https://stackblitz.com/edit/angular-tooltip-directive-fkawer
您使用已弃用的渲染器需要将 InnerHTML 设置为 nativeElement,例如
this.renderer.setElementProperty(el.nativeElement, 'innerHTML', this.tooltipTitle);
或者,如果您使用 Renderer2,则其
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.tooltipTitle);
如果工具提示内容来自外部,您还需要使用DomSanitizer
this.sanitizer.bypassSecurityTrustHtml(content)