如何让<textarea>中的特定命令文字显示为橙色?
实现textarea内特定命令的高亮效果
原生<textarea>本身仅支持统一文本样式,无法单独高亮部分内容,因此可以采用**「输入层+显示层」**的方案:用透明的<textarea>负责接收用户输入,在它下方叠一个<div>渲染带高亮样式的内容,两者保持内容和光标同步,模拟出textarea内部分文字高亮的效果。
具体实现步骤
1. HTML结构
创建容器包裹textarea和高亮显示用的div,确保两者位置重叠:
<div class="editor-container"> <textarea id="codeEditor" placeholder="输入命令:turn right / turn left / forward n"></textarea> <div id="highlightLayer" class="highlight-layer"></div> </div>
2. CSS样式
让textarea和高亮div的布局、字体样式完全一致,textarea设置为透明并置于上层接收输入:
.editor-container { position: relative; width: 500px; height: 200px; border: 1px solid #ccc; border-radius: 4px; } #codeEditor, .highlight-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; padding: 10px; font-family: monospace; font-size: 16px; line-height: 1.5; border: none; outline: none; resize: none; box-sizing: border-box; } #codeEditor { background: transparent; color: transparent; /* 隐藏原生文字 */ caret-color: white; /* 保持光标可见 */ z-index: 1; /* 确保输入层在上方 */ } .highlight-layer { background: #1e1e1e; /* 匹配深色背景 */ color: white; /* 默认文字颜色 */ white-space: pre-wrap; word-wrap: break-word; pointer-events: none; /* 禁止点击,让事件透传到textarea */ } /* 高亮命令的样式 */ .highlight-command { color: orange; }
3. JavaScript逻辑
监听textarea的输入事件,将内容中的目标命令替换为带高亮类的span,同时同步光标位置保证输入体验:
const codeEditor = document.getElementById('codeEditor'); const highlightLayer = document.getElementById('highlightLayer'); // 匹配目标命令的正则:turn right、turn left、forward 数字 const commandRegex = /(turn right|turn left|forward \d+)/g; function updateHighlight() { // 获取输入内容 let content = codeEditor.value; // 替换匹配的命令为高亮span let highlightedContent = content.replace(commandRegex, '<span class="highlight-command">$1</span>'); // 更新高亮层内容 highlightLayer.innerHTML = highlightedContent; // 同步光标位置,避免输入时光标错位 syncCaretPosition(); } function syncCaretPosition() { const selection = window.getSelection(); if (selection.rangeCount === 0) return; const range = selection.getRangeAt(0); const preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(codeEditor); preCaretRange.setEnd(range.endContainer, range.endOffset); // 映射光标到高亮层 const highlightRange = document.createRange(); const textNode = highlightLayer.firstChild; if (textNode) { highlightRange.setStart(textNode, preCaretRange.toString().length); highlightRange.setEnd(textNode, preCaretRange.toString().length); const newSelection = window.getSelection(); newSelection.removeAllRanges(); newSelection.addRange(highlightRange); } } // 实时监听输入更新高亮 codeEditor.addEventListener('input', updateHighlight); // 初始化高亮状态 updateHighlight();
关键说明
- 输入层(textarea)仅负责接收输入和显示光标,用户看不到原生文字;
- 显示层(div)负责渲染带高亮样式的内容,通过
pointer-events: none让输入事件透传到textarea; - 正则表达式精准匹配三类命令,其中
forward \d+匹配forward后跟任意数字的格式; - 光标同步逻辑保证输入时光标位置与视觉显示一致,避免错位问题。
内容的提问来源于stack exchange,提问作者Jahan Manu
相关产品推荐
相关产品推荐

