react-highlight-words
https://github.com/bvaughn/re…
一个React组件,用处:在一段文本中高亮展示某些单词
源码思路
直接返回一个函数式组件
- 最重要是调用
findAll
函数,返回[{start: startIndex, end: endIndex, highlight: boolean}, {同样的结构}]
,将一段句子合理的划分为从前到后的高亮部分和未高亮部分 - 然后遍历
chunks
, 返回高亮和未高亮两种不同的DOM结构
==核心就是将高亮部分和未高亮部分通过数据结构(对象数组)进行标识和区分,便于后续的处理==
findAll
函数是highlight-words-core
模块提供的工具方法,所有后面会讲解这个模块。
/* @flow */
import { findAll } from 'highlight-words-core'
import PropTypes from 'prop-types'
import React from 'react'
Highlighter.propTypes = {
activeClassName: PropTypes.string,
activeIndex: PropTypes.number,
activeStyle: PropTypes.object,
autoEscape: PropTypes.bool,
className: PropTypes.string,
findChunks: PropTypes.func,
highlightClassName: PropTypes.string,
highlightStyle: PropTypes.object,
highlightTag: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
PropTypes.string
]),
sanitize: PropTypes.func,
searchWords: PropTypes.arrayOf(PropTypes.string).isRequired,
textToHighlight: PropTypes.string.isRequired,
unhighlightClassName: PropTypes.string,
unhighlightStyle: PropTypes.object
}
/**
* Highlights all occurrences of search terms (searchText) within a string (textToHighlight).
* This function returns an array of strings and <span>s (wrapping highlighted words).
*/
export default function Highlighter ({
activeClassName = '',
activeIndex = -1,
activeStyle,
autoEscape,
caseSensitive = false,
className,
findChunks,
highlightClassName = '',
highlightStyle = {},
highlightTag = 'mark',
sanitize,
searchWords,
textToHighlight,
unhighlightClassName = '',
unhighlightStyle
}) {
const chunks = findAll({
autoEscape,
caseSensitive,
findChunks,
sanitize,
searchWords,
textToHighlight
})
const HighlightTag = highlightTag
let highlightCount = -1
let highlightClassNames = ''
let highlightStyles
return (
<span className={className}>
{chunks.map((chunk, index) => {
const text = textToHighlight.substr(chunk.start, chunk.end - chunk.start)
if (chunk.highlight) {
highlightCount++
const isActive = highlightCount === +activeIndex
highlightClassNames = `${highlightClassName} ${isActive ? activeClassName : ''}`
highlightStyles = isActive === true && activeStyle != null
? Object.assign({}, highlightStyle, activeStyle)
: highlightStyle
return (
<HighlightTag
className={highlightClassNames}
key={index}
style={highlightStyles}
>
{text}
</HighlightTag>
)
} else {
return (
<span
className={unhighlightClassName}
key={index}
style={unhighlightStyle}
>
{text}
</span>
)
}
})}
</span>
)
}
highlight-words-core
https://github.com/bvaughn/hi…
被
react-highlight-words
和
react-native-highlight-words
模块共享的工具函数
源码思路
主要提供多个工具函数
- findAll
此为核心函数,根据传入的参数,返回
[{start, end, highlight}]
这样的数据结构,分段标识出
textToHighlight
语句的高亮部分及未高亮部分。供给外部进一步使用。
- combineChunks
将
defaultFindChunks
函数返回的chunks进行合并处理,把有重叠的块合并为一个块(若不合并,后续处理则会出现重复文字,与原文内容都不一致了)
- defaultFindChunks
通过正则匹配查找
searchWords
, 返回
[{start, end}, {}]
这样的数据结构
- fillInChunks
该函数接收
chunksToHighlight
,只包含高亮的部分,需要填充出未高亮的部分,才是完整表达出
textToHighlight
,同时更改了数据结构,变成
[{start, end, highlight}]
, 多出
highlight
findAll -》 fillInChunks -》combineChunks -》defaultFindChunks
箭头表示依赖关系,思路上也是层层递进,有顺序的。