如何在React JS中实现类似原生JavaScript的节点创建,适配拼写检查高亮需求
React实现contenteditable拼写检查高亮功能
我使用contenteditable开发了拼写检查功能,该功能会在用户触发keyup事件时执行,识别到的错误词汇将被mark标签包裹。我已经使用原生JavaScript完成了实现,现在需要改用React的方式开发。
原生JavaScript实现代码
let originalNode = document.createElement('p') let textNode = document.createTextNode('Sri Lankan Tamil activists in Britain paid tribute to the victims of the Sri Lankan civil war on Friday by placing the national flower of Tamil') originalNode.appendChild(textNode) let str = 'Tamil' let wholeWordRegExp = new RegExp('\\b' + str + '\\b') let pos = textNode.nodeValue.search(wholeWordRegExp) let newNode = textNode.splitText(pos) let mark = document.createElement('mark') mark.setAttribute("contenteditable", true) textNode.parentNode.insertBefore(mark, newNode) newNode.splitText(str.length) mark.appendChild(newNode) console.log(originalNode) //console.log(originalNode.firstChild)
期望的React实现要求
希望在React中按如下方式创建mark标签:
let mark = React.createElement('mark', {contenteditable: true}, newNode)
实现方案
React是状态驱动渲染的框架,不建议直接操作DOM节点,你可以把原生拆分文本节点的逻辑改成处理字符串,拆分后生成对应的React元素数组渲染即可,实现效果和原生版本一致:
实现思路
- 用正则将原始文本按匹配的关键词拆分为片段数组
- 遍历片段数组,匹配到错误词的部分用要求的方式生成
mark元素,其余片段直接作为文本节点返回 - 绑定
keyup事件维护文本内容状态,更新后自动重新渲染高亮
示例代码
import { useState } from 'react'; function SpellCheckEditor() { // 可编辑区域的文本内容状态 const [content, setContent] = useState('Sri Lankan Tamil activists in Britain paid tribute to the victims of the Sri Lankan civil war on Friday by placing the national flower of Tamil'); // 拼写检查识别到的错误词,可根据你的实际检查逻辑动态更新 const errorWord = 'Tamil'; // 全字匹配正则,加括号保留拆分后的匹配项 const matchReg = new RegExp(`(\\b${errorWord}\\b)`, 'g'); // 生成带高亮的渲染内容 const getHighlightContent = () => { const textFragments = content.split(matchReg); return textFragments.map((fragment, index) => { if (fragment === errorWord) { // 按要求方式创建mark标签 return React.createElement('mark', { key: index, contentEditable: true }, fragment); } return fragment; }); }; // keyup事件处理,同步最新文本内容 const handleKeyUp = (e) => { setContent(e.currentTarget.textContent); // 此处补充你自己的拼写检查逻辑,动态更新错误词列表 }; return ( <p contentEditable onKeyUp={handleKeyUp}> {getHighlightContent()} </p> ); }
内容的提问来源于stack exchange,提问作者bairavand
相关产品推荐
相关产品推荐

