mark.js荧光笔工具和angular自定义管道实现高亮

mark.js是用JavaScript编写的文本荧光笔。

它可以用来动态标记搜索词或自定义正则表达式,并为您提供内置的选项,如变音符号支持,单词搜索,自定义同义词,iframe支持,自定义过滤器,准确性定义,自定义元素,自定义类名称等。

下载

1
npm install mark.js --save

兼容

  • Firefox (30+)
  • Chrome (30+)
  • Safari (7+)
  • Edge (13+)
  • IE (9+)

定义样式

可以自定义高亮的样式

1
2
3
4
mark{
background: orange;
color: black;
}

使用

定义

1
var instance = new Mark(context);

context 是要匹配的内容:可以是一个节点, 也可以是一个nodelist, 来个🌰:

1
2
3
var instance = new Mark(document.querySelector("div.context"));
// or
var instance = new Mark("div.context");

标记

1
this.instance.mark('mark'); // 标记指定元素中所有mark

instance.mark(keyword [, options]); 可以通过options实现更丰富的功能
标记正则匹配部分

1
instance.markRegExp(regexp [, options]);

移除高亮

1
instance.unmark(options);

options详解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var options = {
"element": "mark", //包裹匹配元素的标签
"className": "", // 添加到元素上的class
"exclude": [], //被忽略不匹配的标签
"separateWordSearch": true, //是否不完全匹配(即不需要空格分割)
"accuracy": "partially",// 精确度:partially(标记词语的一部分) complementary(标记整个词) exactly(匹配边界)
"diacritics": true, // 是否兼容音标
"synonyms": {},// 同义词
"iframes": false, // 是否匹配iframes内的部分
"iframesTimeout": 5000, // 多少秒后还未加载出, 就不标记iframes
"acrossElements": false,// 是否夸元素匹配
"caseSensitive": false,// 是否区分大小写
"ignoreJoiners": false,
"ignorePunctuation": [],
"wildcards": "disabled",
"each": function(node){
// node is the marked DOM element
},
"filter": function(textNode, foundTerm, totalCounter, counter){
// textNode is the text node which contains the found term
// foundTerm is the found search term
// totalCounter is a counter indicating the total number of all marks
// at the time of the function call
// counter is a counter indicating the number of marks for the found term
return true; // must return either true or false
},
"noMatch": function(term){
// term is the not found term
},
"done": function(counter){
// counter is a counter indicating the total number of all marks
},
"debug": false,
"log": window.console
};

官网地址 https://markjs.io/

与angular2+出现的问题

在对高亮部分的双向绑定的值改变时,会出现重复高两部分

我觉得导致这个问题是因为mark给高亮的部分加了自己的标签,如:, 所以angular自己的双向绑定的值不在是原来的值了.

解决方案:

1
2
3
4
5
this.marker.unmark() // 取消高亮
data.qaContent = res.qaContent; // 修改双向绑定的值
setTimeout(() => { // 重新高亮
this.marker.mark(this.filter.nativeElement.value.trim());
});

过程中试过直接重新高亮, 但是没有效果. 加了setTimeout把高亮放到这次轮训的最后, 有效. (个人觉得是因为优先处理了高亮才进行双向绑定的渲染, 所以没有生效)

使用管道实现

采用自定义管道实现高亮的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import {Pipe, Injectable, PipeTransform} from '@angular/core';
import {DomSanitizer} from '@angular/platform-browser';

@Pipe({
name: 'keyword'
})
@Injectable()
export class KeywordPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
}
// 传入要标记的文本和标记的颜色,默认红色
transform(val: string, keyword: string, color:string = 'red'): any {

let Reg = new RegExp(keyword, 'i');
if (val) {
let res = val.replace(Reg, `<span style="color: ${color};">${keyword}</span>`);
console.log(res);
return this.sanitizer.bypassSecurityTrustHtml(res);
}
}
}

使用

1
<span [innerHTML]="name|keyword:keyword"></span>