最近做了一个文章发布管理的小项目, 其中一个需求是通过搜索关键字,列出来所有包含关键字的文章, 并且高亮关键字。 于是网上搜索了一圈解决方案,本地做了一个小demo, 记录下来。
step1: 创建一个pipe
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'highlighter'
})
export class HighlighterPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(value: any, args: any, type: string): unknown {
if (!args) return value;
console.log('highlighter...', value, args, type);
if (type === 'full') {
const re = new RegExp("\\b(" + args + "\\b)", 'igm');
value = value.replace(re, '<span style="background-color: #ffe536;">$1</span>');
}
else {
const re = new RegExp(args, 'igm');
value = value.replace(re, '<span style="background-color: #ffe536;">$&</span>');
}
// return value;
return this.sanitizer.bypassSecurityTrustHtml(value);
}
}
step 2: 在angular.module.ts 里导入pipe
@NgModule({
declarations: [
AppComponent,
ArticleComponent,
HighlighterPipe
],
imports: [
BrowserModule,
FormsModule,
MatListModule,
QuillModule.forRoot()
],
providers: [RequestService],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 3: 在html 中使用pipe
# 搜索框
<div class="article_search">
<input
#search
tyep="text"
placeholder="please input search keyword"
(keyup)="searchCreteria(search.value.trim())"
/>
</div>
# 根据关键字搜索出来的文章, 用highlighter pipe 高亮
<div class="article_readonly-mode">
<div *ngIf="!article.isEditable">
<span #keyWords *ngIf="article.showMoreContent" [innerHTML]="article.body.substring(0, 101).concat('...')| highlighter : search.value : 'full'"></span>
<span #keywords *ngIf="!article.showMoreContent" [innerHTML]=" article.body | highlighter : search.value : 'full'">
<!-- {{ article.body }} -->
</span>
<button
*ngIf="article.body.length >= 100"
class="btn_show-more"
click)="showMore(article)"
>
{{ article.showMoreBtnText }}
</button>
</div>
</div>
效果如下:
参考文章
Search and Highlight Text feature using Angular - DEV Community
注意:开始的时候参考上面的文章总是没办法实现关键字高亮,然后使用DomSanitizer的bypassSecurityTrustHtml 解决了问题。 下面是Angular DomSanitizer 提供的一些方法。
DomSanitizer提供的方法
1. sanitize()
为在给定的 SecurityContext 中使用而对 value
进行转义
如果这个值在这个上下文中是可信的,则该方法会解开所包含的安全值,并且直接使用它;否则,这个值就会根据给定的安全上下文净化成安全的,比如替换那些具有不安全协议(例如 javascript:
)的 URL。 该实现负责确保在给定的上下文中可以绝对安全的使用该值。
2. bypassSecurityTrustHtml()
绕过安全检查,并信任给定的值是一个安全的 HTML。只有当要绑定的 HTML 是不安全内容(比如包含 <script>
)而且你确实希望运行这些代码时,才需要使用它。 净化器会确保安全 HTML 的完整性,因此在大多数场景下都不需要使用该方法。
3. bypassSecurityTrustStyle()
绕过安全检查,并信任给定的值是一个安全的样式(CSS)。
4. bypassSecurityTrustScript()
绕过安全检查,并信任给定的值是一个安全的JavaScript。
5. bypassSecurityTrustUrl()
绕过安全检查,并信任给定的值是一个安全的样式 URL。也就是说该值可安全地用在链接或 <img src>
中。
6. bypassSecurityTrustResourceUrl()
绕过安全检查,并信任给定的值是一个安全的资源 URL。也就是说该地址可以安全的用于加载可执行代码,比如 <script src>
或 <iframe src>
。
警告: 使用不可信的用户数据调用此方法将会让你的应用暴露在 XSS 安全风险之下!
https://angular.cn/api/platform-browser/DomSanitizer#description