如何在input/textarea元素中为@开头的提及文本修改颜色?
实现输入框内@提及文本的实时高亮
因为原生<input>和<textarea>无法对局部文本设置差异化样式,所以采用输入框+上层镜像容器的方案:让输入框保持透明仅保留光标,同时用一个重叠的div同步输入内容,在这个div里对@开头的文本做高亮处理,视觉上就像输入框内的文本直接变色了。
具体实现
1. HTML结构
创建包含输入框和镜像容器的父级容器,确保两者能重叠放置:
<div class="input-wrapper"> <textarea id="message-input" placeholder="输入消息..."></textarea> <div id="highlight-mirror"></div> </div>
2. CSS样式
让镜像容器和输入框的样式完全对齐,输入框设为透明仅保留光标:
.input-wrapper { position: relative; width: 400px; height: 120px; } #message-input, #highlight-mirror { position: absolute; top: 0; left: 0; width: 100%; height: 100%; padding: 10px; font-size: 16px; line-height: 1.5; border: 1px solid #ddd; border-radius: 4px; font-family: inherit; white-space: pre-wrap; word-wrap: break-word; } #message-input { background: transparent; color: transparent; caret-color: #333; /* 确保光标可见 */ z-index: 1; /* 输入框在顶层,保证能接收输入 */ } #highlight-mirror { color: #333; pointer-events: none; /* 禁止镜像容器干扰输入操作 */ } .highlight-mention { color: #2563eb; /* @提及文本的高亮颜色 */ font-weight: 500; }
3. JavaScript逻辑
监听输入事件,同步内容到镜像容器,并自动识别@提及文本添加高亮样式:
const input = document.getElementById('message-input'); const mirror = document.getElementById('highlight-mirror'); // 匹配@提及的正则:@开头,跟随字母/数字/下划线,直到遇到空格或标点结束 const mentionRegex = /@([a-zA-Z0-9_]+)/g; input.addEventListener('input', syncHighlight); // 初始化同步 syncHighlight(); function syncHighlight() { // 将输入内容中的@提及替换为带高亮类的span标签 const highlightedContent = input.value.replace(mentionRegex, '<span class="highlight-mention">@$1</span>'); mirror.innerHTML = highlightedContent; }
注意事项
- 确保输入框和镜像容器的样式完全一致(字体、行高、padding等),避免视觉错位
- 如果需要支持中文昵称,可修改正则为
/@([\w\u4e00-\u9fa5]+)/g - 若需处理复杂光标操作(如手动定位光标、多行编辑),需额外添加光标位置同步逻辑(基础场景下上述代码足够)
内容的提问来源于stack exchange,提问作者Daniel Tenan
相关产品推荐
相关产品推荐

