如何为input标签中的每个单词设置背景色且排除空格
解决input内单词高亮但空格不带背景的问题
原生<input>标签的文本内容是作为不可拆分的整体存在的,没法直接给单个单词单独设置样式(包括背景色),所以得用以下两种方案来实现需求:
方案一:用contenteditable元素模拟input
这种方法最直接,把可编辑的div伪装成input,就能像处理<p>标签一样,用<span>包裹每个单词来加背景色,空格自然不会被包裹。
示例代码
<!-- 模拟input的可编辑div --> <div class="input-mock" contenteditable="true" placeholder="输入内容..."></div>
/* 让div看起来和原生input一致 */ .input-mock { width: 300px; padding: 8px 12px; border: 1px solid #ced4da; border-radius: 4px; font-size: 14px; outline: none; } .input-mock:empty:before { content: attr(placeholder); color: #6c757d; } /* 单词高亮样式 */ .input-mock .word-highlight { background-color: #ffeb3b; padding: 2px 4px; border-radius: 2px; }
const mockInput = document.querySelector('.input-mock'); // 监听输入事件,处理文本拆分 mockInput.addEventListener('input', () => { // 获取当前文本,按空格拆分单词和空格 const text = mockInput.textContent; // 用正则拆分出单词和空格(保留空格的位置) const parts = text.split(/(\s+)/); // 清空原有内容 mockInput.innerHTML = ''; parts.forEach(part => { if (part.trim()) { // 非空格内容,用span包裹 const span = document.createElement('span'); span.className = 'word-highlight'; span.textContent = part; mockInput.appendChild(span); } else { // 空格直接添加文本节点 mockInput.appendChild(document.createTextNode(part)); } }); });
方案二:原生input + 视觉模拟层
如果必须使用原生<input>标签,可以在input下方叠一个内容容器,把处理后的高亮文本放在里面,让input透明,实现视觉上的高亮效果,实际输入逻辑还是用原生input。
示例代码
<div class="input-wrapper"> <input type="text" class="real-input" placeholder="输入内容..."> <div class="highlight-layer"></div> </div>
.input-wrapper { position: relative; width: 300px; } /* 原生input设置透明,放在上层 */ .real-input { width: 100%; padding: 8px 12px; border: 1px solid #ced4da; border-radius: 4px; font-size: 14px; background: transparent; position: relative; z-index: 1; outline: none; } /* 高亮层放在下层,和input样式一致 */ .highlight-layer { position: absolute; top: 0; left: 0; width: 100%; padding: 8px 12px; border: 1px solid transparent; border-radius: 4px; font-size: 14px; white-space: pre-wrap; pointer-events: none; /* 不让高亮层干扰输入 */ } .highlight-layer .word-highlight { background-color: #ffeb3b; padding: 2px 4px; border-radius: 2px; }
const realInput = document.querySelector('.real-input'); const highlightLayer = document.querySelector('.highlight-layer'); // 同步input内容到高亮层并处理高亮 realInput.addEventListener('input', () => { const text = realInput.value; const parts = text.split(/(\s+)/); let html = ''; parts.forEach(part => { if (part.trim()) { html += `<span class="word-highlight">${part}</span>`; } else { html += part; } }); highlightLayer.innerHTML = html; });
两种方案里,方案一的交互更接近原生input的体验,方案二则保留了原生input的表单特性,你可以根据实际场景选择。
内容的提问来源于stack exchange,提问作者Aeton
相关产品推荐
相关产品推荐

