angular - 如何在 Angular 指令中添加 html 标签?
问题描述
我有一个工具提示指令,它允许我在将鼠标悬停在元素上时显示工具提示。
但是,我希望在工具提示中显示的文本中能够集成 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;
}
}
工具提示.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
解决方案
您使用不推荐使用的 Renderer 需要将 InnerHTML 设置为 nativeElement ,例如
this.renderer.setElementProperty(el.nativeElement, 'innerHTML', this.tooltipTitle);
或者,如果您使用Renderer2,它的
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.tooltipTitle);
如果 tooltip 内容来自外部,还需要使用DomSanitizer
this.sanitizer.bypassSecurityTrustHtml(content)
推荐阅读
- azure - 具有从表 Storage 复制活动到 CosmosDb 的附加列的动态内容
- r - 根据前一个的值从数据表中删除行
- apache-camel - 在 ServiceMix 的部署文件夹中将骆驼路由部署为 XML 时设置捆绑版本和启动级别
- javascript - 我不能把剑道下拉列表只读
- node.js - 为什么 Intellisense 不适用于 Discord.js?
- java - 如何在Java中的exe文件末尾写一个字符串
- python - 简化 Python 中的一系列 elif 语句
- c# - Stripe PaymentIntent 键未定义 | 无法从控制器传递 ClientSecret 密钥 | ASP.NET MVC
- r - 用样本 ID 标记 ggplot2 箱线图点
- c++ - 除了遗产之外,这个“:”运算符是什么意思?- 使用字符串到字符的转换