如何用React+Tailwind实现输入框输入时高亮特定单词?
在React + Tailwind中不使用dangerouslySetInnerHTML实现输入时高亮特定单词
要实现输入时高亮特定单词且避免使用dangerouslySetInnerHTML,可以通过拆分文本片段的方式,将匹配目标单词的部分用带样式的<span>包裹,其余部分保留纯文本节点,再结合contentEditable实现可输入的高亮效果。以下是具体实现:
import React, { useState, useRef, useEffect } from 'react'; const HighlightInput = () => { const [rawText, setRawText] = useState(''); const inputRef = useRef(null); const targetWord = 'tomato'; const highlightClass = 'text-red-500'; // 组件挂载时聚焦输入区域 useEffect(() => { inputRef.current?.focus(); }, []); // 处理输入,更新原始文本 const handleInput = (e) => { const currentText = e.target.textContent; // 限制输入长度为64字符 if (currentText.length <= 64) { setRawText(currentText); } }; // 将原始文本拆分为带高亮的片段数组 const getHighlightedFragments = () => { if (!rawText) return []; // 用目标单词分割文本,同时保留分割符 const regex = new RegExp(`(${targetWord})`, 'gi'); const fragments = rawText.split(regex); return fragments.map((fragment, index) => { // 判断当前片段是否是目标单词,是则用span包裹 if (fragment.toLowerCase() === targetWord.toLowerCase()) { return ( <span key={index} className={highlightClass}> {fragment} </span> ); } return fragment; }); }; return ( <div className="p-4"> <label className="block mb-2">输入内容(最多64字符):</label> <div ref={inputRef} contentEditable onInput={handleInput} className="border p-2 min-h-[40px] outline-none" > {getHighlightedFragments()} </div> </div> ); }; export default HighlightInput;
实现说明:
- 文本拆分逻辑:通过正则表达式将原始文本按目标单词分割,保留分割后的所有片段,对匹配到的单词片段用带Tailwind高亮样式的
<span>包裹。 - contentEditable处理:使用
contentEditable的<div>作为输入容器,监听onInput事件更新原始文本状态,避免直接操作HTML。 - 长度限制:在输入处理中判断文本长度,确保不超过64字符限制。
- 聚焦处理:组件挂载时自动聚焦输入区域,提升用户体验。
内容的提问来源于stack exchange,提问作者subman mahin
相关产品推荐
相关产品推荐

