React 如何实现TextArea输入时特定关键词的字体颜色修改
原代码无法生效的核心原因
- 原生
<textarea>组件仅支持纯文本内容,你插入的<span>标签会被直接当做普通字符串渲染,不会生效为HTML样式 - 直接将拼接了HTML标签的字符串赋值给textarea的内容,只会显示完整的标签代码,达不到变色效果
实现方案(分层模拟textarea,兼容性最优)
原理是做两层重叠的元素:底层用来渲染带高亮样式的格式化内容,上层放全透明的textarea承接用户输入,两者的字体、字号、行高、边距完全保持一致,用户感知不到分层,只会看到输入的关键词自动变色。
import { useState } from 'react'; export default function App() { const [queryText, setQueryText] = useState(""); const matches = ["select", "where", "from"]; const handleChange = ({ target }) => { setQueryText(target.value); }; // 处理关键词高亮逻辑 const renderHighlightText = () => { // 拆分内容时保留空格、换行符等格式 return queryText.split(/(\s+)/).map((part, idx) => { // 需要大小写不敏感匹配的话,可转为小写后再判断 if (matches.includes(part)) { return <span key={idx} style={{color: 'blue'}}>{part}</span> } return part; }) }; return ( <div style={{position: 'relative', border: '1px solid #ccc', width: 500, minHeight: 120, padding: 8, fontFamily: 'monospace', fontSize: 14, lineHeight: 1.5}}> {/* 底层:带高亮的内容展示层 */} <div style={{whiteSpace: 'pre-wrap', wordBreak: 'break-all'}}> {renderHighlightText()} </div> {/* 上层:透明的输入承接层 */} <textarea name="description" placeholder="Description" value={queryText} onChange={handleChange} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', margin: 0, padding: 8, border: 'none', outline: 'none', background: 'transparent', color: 'transparent', caretColor: '#000', // 保留黑色输入光标 font: 'inherit', lineHeight: 'inherit', resize: 'none' }} /> </div> ); }
也可以使用
contenteditable属性的div实现,但需要自行处理光标定位、输入过滤等逻辑,开发成本较高,容易出现兼容性问题,更推荐上述分层模拟方案。
注意事项
- 两层元素的字体、字号、行高、内边距必须完全一致,才不会出现输入内容和底层高亮内容错位的问题
- 如果需要支持多行自动扩容,可以配合文本高度计算逻辑同步调整外层容器和textarea的高度
内容的提问来源于stack exchange,提问作者JsLearner
相关产品推荐
相关产品推荐

