textarea模拟高亮关键字
<div class="hEdiv" data-prev="1"><pre class="hEpre"><style>
.tMid { text-align: center; }
.hlight { background: tan; }
/* 编辑区域容器 */
.wrap {
width: 600px;
height: 460px;
box-sizing: border-box;
padding: 0;
margin: 20px auto 0;
position: relative;
}
/* 编辑区域内 pre 和 textarea 核心属性 */
.edCommon {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
font: normal 18px/24px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
background: none;
white-space: pre-wrap;
word-break: break-all;
box-sizing: border-box;
overflow: auto;
border: 1px solid gray;
outline: none;
resize: none;
padding: 12px;
margin: 0;
transition: 1s;
}
/* pre 初始状态 */
#pre { color: blue; transform: translate(-50%, 0); }
/* textarea 初始状态 */
#ta { color: black; transform: translate(50%, 0); }
</style>
<h2 class="tMid">textarea模拟高亮关键字</h2>
<p class="tMid">检验方法:在文本框输入任何文字后选择任意文字,匹配选择文字的字符将以背景高亮的形式呈现。编辑区内两个元素合并、分离状态下均可操作。</p>
<!-- 编辑区 :pre 在前 textarea 在后 -->
<div class="wrap">
<pre id="pre" class="edCommon">pre</pre>
<textarea id="ta" class="edCommon" placeholder="请输入 ..."></textarea>
</div>
<p class="tMid"><button onclick="separateElms(this)">合并</button></p>
<script>
let keyword = ''; // 查找关键词
// 辅助演示 :两个元素的 分离/叠加
function separateElms(btn) {
if (btn.textContent === '分离') {
ta.style.transform = 'translate(50%, 0)';
pre.style.transform = 'translate(-50%, 0)';
pre.style.color = 'blue';
} else {
ta.style.transform = 'translate(0, 0)';
pre.style.transform = 'translate(0, 0)';
pre.style.color = 'transparent';
}
btn.textContent = btn.textContent === '分离' ? '合并' : '分离';
}
function syncScroll(e) {
const targetElm = e.target === pre ? ta : pre;
targetElm.scrollTop = e.target.scrollTop;
targetElm.scrollLeft = e.target.scrollLeft;
}
// 核心函数 :高亮关键词函数
function hlight() {
if (!ta.value) {
pre.innerHTML = '';
return;
}
// 处理 textarea 内容(转义尖括号)
let code = ta.value.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
// 若查找关键词存在高亮所有匹配的关键词
if (keyword) code = code.replaceAll(
keyword,
`<span class="hlight">${keyword}</span>`
);
pre.innerHTML = code; // 处理结果呈现在 pre 里
}
ta.oninput = () => hlight(); // textarea 输入时处理高亮关键字
ta.onscroll = (e) => syncScroll(e); // 滚动同步
pre.onscroll = (e) => syncScroll(e); // 滚动同步
// 编辑框选择事件
ta.onmouseup = () => {
const start = ta.selectionStart;
const end = ta.selectionEnd;
if (start === end) return;
keyword = ta.value.substring(start, end);
if (keyword) hlight(); // 有关键词高亮显示
};
</script>
</pre></div>
<script type="module">
import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
const divs = document.querySelectorAll('.hEdiv');
const pres = document.querySelectorAll('.hEpre');
divs.forEach((div,idx) => hl.hl(div, pres));
</script> 说明:
(一)textarea 自身只支持一个全局背景色、一个全局文本色,它并不能高亮渲染所有匹配的查找关键词;
(二)本例利用叠加技术将一个 pre 和 一个 textarea 放在一起(演示效果中的“合并状态)。pre 元素可以较好地和 textarea 元素共享核心 CSS 属性;
(三)可能存在的问题:textarea 的 value 转到 pre 中,在 pre 中实现高亮关键词效果,必须使用 HTML 格式,这对绝大多数文本没问题,但如果 textarea 的文本是复杂的相关代码,因为转移问题可能会出现偏差,因此上例中简单的尖括号转义可能达不到要求。 复制了一段文字,这个能很好地找到相同的字,真方便啊{:4_187:} 红影 发表于 2026-7-6 21:38
复制了一段文字,这个能很好地找到相同的字,真方便啊
这个演示对普通文本的匹配和高亮没问题,但对特殊文本的处理机制还远远不够,需要深入处理。
但这个仅是简单演示,个人认为:限于篇幅和水平问题,就酱紫吧。 我若是想写点小资一类的文案,一定会选择这样处理一些高亮字,便捷好用。感谢分享,马老师晚上好!{:4_204:}{:4_190:}
马黑黑 发表于 2026-7-6 21:48
这个演示对普通文本的匹配和高亮没问题,但对特殊文本的处理机制还远远不够,需要深入处理。
但这个仅 ...
能匹配普通文本就很好很实用啊,我们又不做复杂文本{:4_173:} 红影 发表于 2026-7-8 10:05
能匹配普通文本就很好很实用啊,我们又不做复杂文本
其实所谓的复杂文本,指的是 HTML 实体,例如:
<、>、&gt 之类的东东,这些东东远超乎想象,非常复杂 霜染枫丹 发表于 2026-7-8 01:10
我若是想写点小资一类的文案,一定会选择这样处理一些高亮字,便捷好用。感谢分享,马老师晚上好!{:4_204: ...
那个,HTML的话,通过设置 <mark>高亮文字</mark> 即可,并不复杂 很实用,尤其批量查找关键词,谢谢马老师精彩分享{:4_190:} 杨帆 发表于 2026-7-10 19:45
很实用,尤其批量查找关键词,谢谢马老师精彩分享
{:4_180:} 马黑黑 发表于 2026-7-10 19:12
其实所谓的复杂文本,指的是 HTML 实体,例如:
看着就觉得好复杂啊。 红影 发表于 2026-7-12 09:11
看着就觉得好复杂啊。
关键是,不做处理的话,它们会乱窜或根本就无法匹配命中 马黑黑 发表于 2026-7-12 17:29
关键是,不做处理的话,它们会乱窜或根本就无法匹配命中
想找到要找的,还挺不容易。 红影 发表于 2026-7-14 19:29
想找到要找的,还挺不容易。
对。即便是肉眼可见的匹配,在变成世界,它依然是复杂的 马黑黑 发表于 2026-7-14 19:39
对。即便是肉眼可见的匹配,在变成世界,它依然是复杂的
是的,就像机器人,即使很很简单的动作,实现也是很难的。 红影 发表于 2026-7-14 20:42
是的,就像机器人,即使很很简单的动作,实现也是很难的。
嗯嗯,大约如此 马黑黑 发表于 2026-7-14 20:58
嗯嗯,大约如此
所以学起来也不容易。 红影 发表于 2026-7-14 21:51
所以学起来也不容易。
不易也不难 马黑黑 发表于 2026-7-15 18:05
不易也不难
嗯嗯,对认真的人不难{:4_173:} 红影 发表于 2026-7-17 17:46
嗯嗯,对认真的人不难
嗯嗯,难就难在认真二字而已