适用范围:行内元素、行内块元素;(注意多行文本可能存在浏览器内核版本限制)
使用css的属性实现
- overflow、whiteSpace、textOverflow进行单行文本的省略号...显示;
- webkitBoxOrient 、webkitLineClamp、textOverflow进行多行文本缩略,(主要用webkitLineClamp)
import { Directive, ElementRef, AfterViewInit, Input } from '@angular/core'
@Directive({
selector: '[textEllipsis]',
})
export class TextEllipsisDirective implements AfterViewInit {
@Input() lineClamp: string | undefined
constructor(private elementRef: ElementRef) {}
ngAfterViewInit() {
const element: HTMLElement = this.elementRef.nativeElement
this.setEllipsis(element, this.lineClamp)
this.checkOverflow(element)
}
setEllipsis(element, lineClamp) {
if (!lineClamp || lineClamp === '1') {
element.style.overflow = 'hidden'
element.style.whiteSpace = 'nowrap'
element.style.textOverflow = 'ellipsis'
} else {
element.style.overflow = 'hidden'
element.style.display = '-webkit-box'
element.style.webkitBoxOrient = 'vertical'
element.style.webkitLineClamp = this.lineClamp ?? '2'
element.style.textOverflow = 'ellipsis'
}
}
private checkOverflow(element: HTMLElement) {
let widthOrHeight =
!this.lineClamp || this.lineClamp === '1' ? 'Width' : 'Height'
setTimeout(() => {
if (
element[`scroll${widthOrHeight}`] > element[`client${widthOrHeight}`]
) {
element.title = element.textContent.trim()
}
})
}
}
angular中替换setTimeout,使用ChangeDetectorRef确保视图更新完成后再进行变更检查
import { Directive, ElementRef, AfterViewInit, ChangeDetectorRef, Input } from '@angular/core'
@Directive({
selector: '[textEllipsis]',
})
export class TextEllipsisDirective implements AfterViewInit {
@Input() lineClamp: string | undefined
constructor(
private elementRef: ElementRef,
private cdr: ChangeDetectorRef // 注入 ChangeDetectorRef
) {}
ngAfterViewInit() {
const element: HTMLElement = this.elementRef.nativeElement
this.setEllipsis(element, this.lineClamp)
// 直接调用 checkOverflow,确保元素已渲染完成
this.checkOverflow(element)
}
setEllipsis(element: HTMLElement, lineClamp: string | undefined) {
if (!lineClamp || lineClamp === '1') {
element.style.overflow = 'hidden'
element.style.whiteSpace = 'nowrap'
element.style.textOverflow = 'ellipsis'
} else {
element.style.overflow = 'hidden'
element.style.display = '-webkit-box'
element.style.webkitBoxOrient = 'vertical'
element.style.webkitLineClamp = this.lineClamp ?? '2'
element.style.textOverflow = 'ellipsis'
}
}
private checkOverflow(element: HTMLElement) {
let widthOrHeight =
!this.lineClamp || this.lineClamp === '1' ? 'Width' : 'Height'
this.cdr.detectChanges()
if (
element[`scroll${widthOrHeight}`] > element[`client${widthOrHeight}`]
) {
element.title = element.textContent?.trim() ?? ''
}
}
}