You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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);
}

优化建议

如果追求更高性能,可避免重复处理字符串,直接通过控制父元素类来切换模糊效果:

  1. 修改组件类的toggleBlur方法:
toggleBlur(): void {
  this.isBlurred = !this.isBlurred;
}
  1. 模板调整为:
<p [class.blur-enabled]="isBlurred" [innerHTML]="processedHtml" (click)="toggleBlur()"></p>
  1. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:25:19