You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中输入框内特定文本的样式定制方案:实现指定字符单独变色

Absolutely! You can totally pull this off in React—just know that standard <input> or <textarea> elements won’t cut it, since they don’t allow styling specific segments of their text. Here are two reliable approaches, using both plain CSS/Tailwind and React logic:

Approach 1: Build a Custom ContentEditable Component

We’ll use a contenteditable div (which supports inline HTML styling) and handle text formatting + cursor position manually.

Step 1: Add Styling

Plain CSS:

.highlight-separator {
  color: #ef4444; /* Bright red */
  font-weight: bold;
}

Tailwind CSS:

No extra CSS needed—we’ll use inline Tailwind classes directly in our component.

Step 2: The React Component

import { useState, useRef, useEffect } from 'react';

const HighlightedInput = () => {
  const [content, setContent] = useState('Step1: abc // Step2: efg // Step3: hij');
  const editableRef = useRef(null);

  // Save current cursor position before re-rendering
  const saveCursorPos = () => {
    const selection = window.getSelection();
    if (!selection.rangeCount) return null;
    const range = selection.getRangeAt(0);
    const preRange = range.cloneRange();
    preRange.selectNodeContents(editableRef.current);
    preRange.setEnd(range.startContainer, range.startOffset);
    return preRange.toString().length;
  };

  // Restore cursor position after content updates
  const restoreCursorPos = (pos) => {
    if (pos === null || !editableRef.current) return;
    const selection = window.getSelection();
    const range = document.createRange();
    const textNode = editableRef.current.firstChild;
    range.setStart(textNode, pos);
    range.setEnd(textNode, pos);
    selection.removeAllRanges();
    selection.addRange(range);
  };

  const handleInput = (e) => {
    const cursorPos = saveCursorPos();
    const rawText = e.target.innerText;
    
    // Replace "//" with styled spans
    const formattedText = rawText.replace(
      /(\/\/)/g,
      // Use this line for plain CSS:
      '<span class="highlight-separator">$1</span>'
      // Use this line for Tailwind:
      // '<span class="text-red-500 font-bold">$1</span>'
    );
    
    setContent(formattedText);
    // Restore cursor after DOM updates
    setTimeout(() => restoreCursorPos(cursorPos), 0);
  };

  // Sync state to the contenteditable div
  useEffect(() => {
    if (editableRef.current) {
      editableRef.current.innerHTML = content;
    }
  }, [content]);

  return (
    <div
      ref={editableRef}
      contentEditable
      onInput={handleInput}
      className="border rounded-md p-2 min-h-[60px] focus:outline-none focus:ring-2 focus:ring-blue-500"
      suppressContentEditableWarning={true}
    />
  );
};

export default HighlightedInput;

Approach 2: Use a Third-Party Library (Simpler!)

For a faster solution, use react-contenteditable—it handles low-level contentEditable quirks (like cursor position) out of the box.

Step 1: Install the Library

npm install react-contenteditable
# or
yarn add react-contenteditable

Step 2: The Component

import { useState } from 'react';
import ContentEditable from 'react-contenteditable';

const HighlightedInputWithLib = () => {
  const [content, setContent] = useState('Step1: abc // Step2: efg // Step3: hij');

  const handleChange = (e) => {
    const rawText = e.target.value;
    // Format text with Tailwind styles (swap for plain CSS class if needed)
    const formattedText = rawText.replace(/(\/\/)/g, '<span class="text-red-500 font-bold">$1</span>');
    setContent(formattedText);
  };

  return (
    <ContentEditable
      html={content}
      onChange={handleChange}
      className="border rounded-md p-2 min-h-[60px] focus:outline-none focus:ring-2 focus:ring-blue-500"
    />
  );
};

export default HighlightedInputWithLib;

Key Notes & Enhancements

  • XSS Safety: If your input is user-facing and might include untrusted HTML, use a sanitization library like dompurify to clean the formatted content before rendering. Example:
    import DOMPurify from 'dompurify';
    // ...
    const formattedText = DOMPurify.sanitize(rawText.replace(/(\/\/)/g, '<span class="text-red-500 font-bold">$1</span>'));
    
  • Flexible Matching: Adjust the regex /(\/\/)/g to match other patterns (e.g., /Step\d+/g to highlight step numbers).
  • Browser Compatibility: contenteditable works across all modern browsers, but test edge cases like copy-pasting text.

内容的提问来源于stack exchange,提问作者Debanjan Tewary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:07:37