需求: 鼠标右键弹出标记和取消标记按钮,可以显示历史标记文本,可以多个标记及重复标记。 这里主要记录显示历史标记文本如何实现
目前历史标记接口给的数据格式是
{startIndex:'4,1,2,0,2',endIndex:'6,3,4,2,4',isMark:'1,0,1,0,1'}, isMark,0代表取消标记,1代表标记。
1,首先需要搞清楚渲染到页面的数据格式
```handleHistoryTemplate = () => {
const {context} = this.props;
const {text, markRange} = context;
return markRange ? (
<>
{text.slice(0, markRange[0]}
{
Array(markRange.length/2).fill(0).map((item,index) => {
return (
<>
<span className="highlighted can-select">
{text.slice(markRange[2*index], markRange[2*index+1]+1}
</span>
{text.slice(markRange[2*index+1]+1, markRange[2*index+2]}
</>
)
}
</>
):text;
}
**由于上面的渲染结构可知,需要的是从小到大的有序高亮下标集合 如[1,2,4,5,8,10]**
2,将从接口中拿到的字符串数组通过处理,最终生成从小到大的有序高亮下标集合
(排除交叉标记,重复标记,及后面的取消标记等情况)
从接口拿到的数据 const lists = {start_index:'4,1,2,0,2',end_index:'6,3,4,2,4',is_mark:'1,0,1,0,1'}
lists.forEach((lItem, index) => {
const {start_index, end_index, is_mark} = lItem;
let startIndex = start_index && start_index.split(',').map(Number);
let endIndex = end_index && end_index.split(',').map(Number);
let isMark = is_mark && is_mark.split(',').map(Number);
let arr = isMark && new Array(isMark.length).fill([]) || [];
isMark && isMark.forEach((item, index) => {
arr[index] = [startIndex[index], endIndex[index], isMark[index]];
})
let mardRange = isMark && this.getMarkRanges(this.getMarkIndex(arr));
lItem = Object.assign(lItem, mardRange)
})
// 获取标记的下标数组
getMarkIndex = (arr) => {
const maxEnd = Math.max(...arr.map((range) => range[1]));
const marks = Array(maxEnd + 1).fill(0);
arr.forEach((range) => {
const start = range[0];
const end = range[1];
const mark = range[2];
if(mark == 1) {
for(let i = start; i <= end; i++) {
marks[i] = 1;
}
} else {
for(let i = start; i <= end; i++) {
marks[i] = 0;
}
}
})
const output = [];
marks.map((num, index) => {
num == 1 && output.push(index)
})
return output
}
// 获取标记的下标区间数组
getRanges(arr) {
let results = [];
let start = arr[0];
let end = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] !== end + 1) {
results.push(start, end);
start = arr[i];
end = arr[i];
} else {
end = arr[i];
}
}
start && results.push(start, end);
return results;
}