wxuande 2019-06-26
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> ) }
https://github.com/bvaughn/hi...
被react-highlight-words
和react-native-highlight-words
模块共享的工具函数主要提供多个工具函数
[{start, end, highlight}]
这样的数据结构,分段标识出textToHighlight
语句的高亮部分及未高亮部分。供给外部进一步使用。defaultFindChunks
函数返回的chunks进行合并处理,把有重叠的块合并为一个块(若不合并,后续处理则会出现重复文字,与原文内容都不一致了)searchWords
, 返回[{start, end}, {}]
这样的数据结构chunksToHighlight
,只包含高亮的部分,需要填充出未高亮的部分,才是完整表达出textToHighlight
,同时更改了数据结构,变成 [{start, end, highlight}]
, 多出highlight
findAll -》 fillInChunks -》combineChunks -》defaultFindChunks
箭头表示依赖关系,思路上也是层层递进,有顺序的。