找回密码
 立即注册
搜索
查看: 10|回复: 1

textarea模拟高亮关键字 转自马黑黑教程专版

[复制链接]

1455

主题

3114

回帖

1万

积分

管理员

积分
12512
发表于 昨天 09:10 | 显示全部楼层 |阅读模式
   马黑黑教程专版   https://www.huachaowang.com/forum.php?mod=viewthread&tid=94287&extra=page%3D1



<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>合并</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>

1455

主题

3114

回帖

1万

积分

管理员

积分
12512
 楼主| 发表于 昨天 09:11 | 显示全部楼层
说明:

(一)textarea 自身只支持一个全局背景色、一个全局文本色,它并不能高亮渲染所有匹配的查找关键词;

(二)本例利用叠加技术将一个 pre 和 一个 textarea 放在一起(演示效果中的“合并状态)。pre 元素可以较好地和 textarea 元素共享核心 CSS 属性;

(三)可能存在的问题:textarea 的 value 转到 pre 中,在 pre 中实现高亮关键词效果,必须使用 HTML 格式,这对绝大多数文本没问题,但如果 textarea 的文本是复杂的相关代码,因为转移问题可能会出现偏差,因此上例中简单的尖括号转义可能达不到要求。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

协同嘉业科技有限公司 ( 京ICP备2024053108号-1 )

GMT+8, 2026-7-12 02:38 , Processed in 0.086003 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表