React實(shí)現(xiàn)模糊搜索和關(guān)鍵字高亮的示例代碼
背景
公司需要一個(gè)可視化頁面,作為Redis查詢展示的工具,方便同事進(jìn)行快速檢索。
要求將后端返回的報(bào)文,完整展現(xiàn)在識(shí)圖中,并且可以提供關(guān)鍵詞檢索和關(guān)鍵詞點(diǎn)亮的功能,以便快速定位關(guān)鍵詞。
整體效果預(yù)覽:
主要功能
點(diǎn)擊搜索:返回的大字符串形式報(bào)文被組裝成JSON的格式,點(diǎn)擊搜索匹配相應(yīng)字段, 并高亮顯示
點(diǎn)擊區(qū)分大小寫:模糊匹配 OR 精確匹配
查找下一個(gè):被選中的字段,往下移動(dòng)一個(gè),下一個(gè)的背景顏色切換為另一高亮色
解決
- 匹配到的文本,動(dòng)態(tài)插入樣式
- 使用正則解決匹配問題
- 點(diǎn)擊下一個(gè)時(shí),動(dòng)態(tài)切換類名和背景色
代碼實(shí)現(xiàn)
僅僅貼出主要代碼
DOM
... <Input value={this.state.txt} placeholder="請(qǐng)輸入檢索內(nèi)容" onChange={e => this.setState({txt: e.target.value})} ></Input> <Button onClick={this.dispatchHighLightText}> 搜索 </Button> ... <CheckBos checked={this.state.isCheck} onChange={e => this.setState({isCheck: e.target.checked})} > 區(qū)分大小寫 </CheckBos> ... <Button onClick={this.searchToNext} > 查找下一個(gè) </Button> ... <pre dangerouslySetInnerHTML={{__html: this.state.information}} contentEditable > {/*動(dòng)態(tài)插入html的容器*/} </pre>
CSS
// 每個(gè)匹配到的都有的類名 .highLight{ background-color: #a9a9a9; } // 點(diǎn)擊下一個(gè)時(shí)的類名,默認(rèn)為第一個(gè) .current{ background-color: #32aaf8; }
JS
點(diǎn)擊搜索時(shí)
colorIndex = 0; // 初始化高亮標(biāo)記 _information = ''; // 文本備份 dispatchHighLightText = () => { const {txt} = this.state; // 檢索內(nèi)容 if(!txt){ message.warning("請(qǐng)先輸入查詢條件"); return; } // 重置高亮標(biāo)記 colorIndex = 0; const regex = new RegExp(txt, this.state.isCheck ? 'g' : 'gi'); // 不勾選 => 模糊匹配 // 由于每次插入樣式都會(huì)污染文本,所以每次都需要從備份文本中重新渲染 const newInformation = _information; const hightLightTxt = newInformation.replace(regex, (match,index) => `<span class="highLight"> ${match} </span>`); this.setState({infomation: hightLightTxt}, () => { // 視圖更新渲染然后,獲取到dom let highLightEle = document.querySelectorAll('.highLight'); this.updateHeight(highLightEle) }); // render } // 點(diǎn)亮目標(biāo)關(guān)鍵字 updateHeight = (highLightEle) => { highLightEle.forEach((element, index) => { if(index === colorIndex){ element.classList.add('current'); element.scrollIntoView({ behavior: 'smooth', block: 'center'}); }else{ element.classList.remove('current'); } }) }
點(diǎn)擊 “下一個(gè)”
searchToNext = () => { let highLightEle = document.querySelectorAll('.highLight'); if(heighLightEle.length){ colrIndex = (colorIndex + 1 + highLightEle.length) % highLightEle.length; this.updateHeight(highLightEle) } }
反思
- 本來想用偏移量window.getSelection 和 document.createRange 以及相關(guān)api模擬富文本實(shí)現(xiàn)光標(biāo)跳轉(zhuǎn)定位的,可是發(fā)現(xiàn)偏移量不好確定(小菜雞)
- 每次渲染的時(shí)候需要拿新的備份的文本進(jìn)行替換,不要用臟數(shù)據(jù)
- pre標(biāo)簽可以很好的保留文本原來的樣式,不能用textarea
- dangerouslySetInnerHTML接收的是一個(gè)對(duì)象
以上就是React實(shí)現(xiàn)模糊搜索和關(guān)鍵字高亮的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于React模糊搜索和關(guān)鍵字高亮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React中useRef與useState的使用與區(qū)別
本文介紹了React中兩個(gè)常用的鉤子useRef和useState,包含比較它們的功能并提供示例來說明它們的用法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-11-11淺析react里面如何封裝一個(gè)通用的Ellipsis組件
這篇文章主要為大家詳細(xì)介紹了在react里面如何封裝一個(gè)通用的Ellipsis組件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12react-router-dom v6版本跳轉(zhuǎn)路徑的實(shí)現(xiàn)方法
這篇文章主要介紹了react-router-dom v6版本跳轉(zhuǎn)路徑的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Electron打包React生成桌面應(yīng)用方法詳解
這篇文章主要介紹了React+Electron快速創(chuàng)建并打包成桌面應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12基于react項(xiàng)目打包c(diǎn)ss引用路徑錯(cuò)誤解決方案
這篇文章主要介紹了基于react項(xiàng)目打包c(diǎn)ss引用路徑錯(cuò)誤解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10react-router JS 控制路由跳轉(zhuǎn)實(shí)例
這篇文章主要介紹了react-router JS 控制路由跳轉(zhuǎn)實(shí)例,react實(shí)現(xiàn)路由可以直接使用react-router。有興趣的可以了解一下2017-06-06React獲取組件對(duì)應(yīng)的DOM元素多種實(shí)現(xiàn)方法
本文主要介紹了React中獲取組件對(duì)應(yīng)DOM元素的多種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02