如何在Angular中模糊<p>标签内所有指定子串并支持点击还原
Angular实现文本指定子串批量模糊与点击取消功能
需求说明
需在Angular项目中实现:将<p>标签内所有指定子串(大小写不敏感,出现次数不固定)添加模糊效果,点击模糊子串或对应段落可取消模糊。此前使用indexOf仅能处理子串首次出现,无法覆盖所有匹配项。
核心解决方案
通过全局正则表达式匹配所有目标子串,将原文本拆分为「普通文本片段」和「需模糊的子串片段」,再利用Angular的安全HTML绑定渲染带样式的DOM元素,同时绑定点击事件控制模糊状态。
具体实现代码
1. 组件类逻辑
import { Component, OnInit } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Component({ selector: 'app-text-blur', templateUrl: './text-blur.component.html', styleUrls: ['./text-blur.component.css'] }) export class TextBlurComponent implements OnInit { originalText = 'Tomorrow I will have to go to London. Tomorrow is the day it will happen. My only hope is tomorrow.'; targetSubstring = 'tomorrow'; isBlurred = true; // 模糊状态开关 processedHtml: SafeHtml | undefined; constructor(private sanitizer: DomSanitizer) {} ngOnInit(): void { this.renderText(); } // 处理文本并生成带模糊样式的HTML renderText(): void { if (!this.originalText || !this.targetSubstring) { this.processedHtml = this.sanitizer.bypassSecurityTrustHtml(this.originalText); return; } // 构建不区分大小写的全局匹配正则 const matchRegex = new RegExp(`(${this.targetSubstring})`, 'gi'); // 拆分文本为普通片段与匹配片段的数组 const textFragments = this.originalText.split(matchRegex); // 遍历片段,为匹配项添加模糊样式和点击事件 const htmlSegments = textFragments.map(fragment => { if (fragment.toLowerCase() === this.targetSubstring.toLowerCase()) { return `<span class="${this.isBlurred ? 'blurred-text' : ''}">${fragment}</span>`; } return fragment; }); // 标记HTML为安全,避免Angular XSS拦截 this.processedHtml = this.sanitizer.bypassSecurityTrustHtml(htmlSegments.join('')); } // 切换模糊状态 toggleBlur(): void { this.isBlurred = !this.isBlurred; this.renderText(); } }
2. 模板代码
<p [innerHTML]="processedHtml" (click)="toggleBlur()"></p>
3. CSS样式
.blurred-text { filter: blur(4px); cursor: pointer; transition: filter 0.2s ease; } .blurred-text:hover { filter: blur(2px); }
优化建议
如果追求更高性能,可避免重复处理字符串,直接通过控制父元素类来切换模糊效果:
- 修改组件类的
toggleBlur方法:
toggleBlur(): void { this.isBlurred = !this.isBlurred; }
- 模板调整为:
<p [class.blur-enabled]="isBlurred" [innerHTML]="processedHtml" (click)="toggleBlur()"></p>
- CSS补充:
.blur-enabled .blurred-text { filter: blur(4px); }
这样只需初始化时处理一次文本,后续仅通过CSS类切换状态,性能更优。
复用性优化:封装为Angular管道
若需在多个组件复用该功能,可封装成管道:
import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Pipe({ name: 'blurSubstrings' }) export class BlurSubstringsPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(text: string, target: string, isBlurred: boolean): SafeHtml { if (!text || !target) return this.sanitizer.bypassSecurityTrustHtml(text); const matchRegex = new RegExp(`(${target})`, 'gi'); const fragments = text.split(matchRegex); const html = fragments.map(frag => { if (frag.toLowerCase() === target.toLowerCase()) { return `<span class="${isBlurred ? 'blurred-text' : ''}">${frag}</span>`; } return frag; }).join(''); return this.sanitizer.bypassSecurityTrustHtml(html); } }
模板使用示例:
<p [class.blur-enabled]="isBlurred" (click)="toggleBlur()"> {{ originalText | blurSubstrings: targetSubstring: isBlurred }} </p>
内容的提问来源于stack exchange,提问作者Jo Janssen
相关产品推荐
相关产品推荐

