You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JavaScript实现textarea与div选中文本的同步高亮效果

文本选中同步高亮实现代码

前置说明

原生<textarea>为纯文本表单控件,不支持内部插入HTML标签实现自定义局部高亮,因此以下实现提供两种可选方案,可根据实际需求选择:

  • 方案1:保留原生<textarea>,选中内容后仅同步高亮div内的匹配文本,textarea内选中区域使用浏览器默认选中样式
  • 方案2:使用带contenteditable属性的div模拟textarea功能,支持两个区块双向同步高亮匹配文本

方案1:保留原生textarea实现

完整可运行代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <style>
    /* 自定义高亮样式,可自行修改颜色 */
    .highlight {
      background-color: #ffeb3b;
      color: #000;
    }
    textarea {
      width: 100%;
      height: 150px;
      margin: 10px 0;
      padding: 8px;
      box-sizing: border-box;
    }
    .content-div {
      border: 1px solid #ccc;
      padding: 8px;
      min-height: 150px;
      margin: 10px 0;
    }
  </style>
</head>
<body>
  <!-- 无id无class的textarea,符合需求 -->
  <textarea>测试文本内容,选中我看看效果,你可以随便修改这段文字,选中任意部分都会同步在下方div里高亮相同的内容哦。</textarea>
  <!-- 对应需要同步高亮的div -->
  <div class="content-div">测试文本内容,选中我看看效果,你可以随便修改这段文字,选中任意部分都会同步在下方div里高亮相同的内容哦。</div>

  <script>
    // 缓存原始div内容,用于清除高亮时恢复
    let originDivContent = document.querySelector('.content-div').innerText;
    const textarea = document.querySelector('textarea');
    const contentDiv = document.querySelector('.content-div');

    // 清除所有高亮
    function clearHighlight() {
      contentDiv.innerText = originDivContent;
    }

    // 高亮匹配文本
    function highlightMatchedText(selectedText) {
      clearHighlight();
      if (!selectedText.trim()) return;
      // 正则转义特殊字符
      const escapedText = selectedText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
      const reg = new RegExp(escapedText, 'g');
      contentDiv.innerHTML = originDivContent.replace(reg, '<span class="highlight">$&</span>');
    }

    // 监听textarea选中事件
    textarea.addEventListener('select', function() {
      const start = this.selectionStart;
      const end = this.selectionEnd;
      const selected = this.value.substring(start, end);
      highlightMatchedText(selected);
    });

    // 监听div内的选中事件
    contentDiv.addEventListener('mouseup', function() {
      const selection = window.getSelection ? window.getSelection() : document.getSelection();
      const selected = selection.toString();
      highlightMatchedText(selected);
    });

    // 点击空白处清除高亮
    document.addEventListener('click', function(e) {
      if (e.target !== textarea && e.target !== contentDiv && !contentDiv.contains(e.target)) {
        clearHighlight();
      }
    });

    // 同步textarea和div的内容,修改textarea时div内容同步更新
    textarea.addEventListener('input', function() {
      originDivContent = this.value;
      contentDiv.innerText = originDivContent;
    });
  </script>
</body>
</html>

方案2:contenteditable div模拟textarea(支持双向高亮)

如果需要两个区域都支持自定义高亮,可使用此方案,代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <style>
    .highlight {
      background-color: #ffeb3b;
      color: #000;
    }
    /* 模拟textarea样式 */
    .simulate-textarea {
      width: 100%;
      height: 150px;
      margin: 10px 0;
      padding: 8px;
      border: 1px solid #ccc;
      box-sizing: border-box;
      overflow-y: auto;
      white-space: pre-wrap;
      word-break: break-all;
      outline: none;
    }
    .content-div {
      border: 1px solid #ccc;
      padding: 8px;
      min-height: 150px;
      margin: 10px 0;
    }
  </style>
</head>
<body>
  <!-- 模拟textarea的可编辑div -->
  <div class="simulate-textarea" contenteditable="true">测试文本内容,选中我看看效果,你可以随便修改这段文字,选中任意部分都会同步在另一个区块里高亮相同的内容哦。</div>
  <!-- 对应需要同步高亮的div -->
  <div class="content-div">测试文本内容,选中我看看效果,你可以随便修改这段文字,选中任意部分都会同步在另一个区块里高亮相同的内容哦。</div>

  <script>
    const editArea = document.querySelector('.simulate-textarea');
    const contentDiv = document.querySelector('.content-div');
    // 缓存原始内容
    let originEditContent = editArea.innerText;
    let originDivContent = contentDiv.innerText;

    function clearAllHighlight() {
      editArea.innerText = originEditContent;
      contentDiv.innerText = originDivContent;
    }

    function highlightBoth(selectedText) {
      clearAllHighlight();
      if (!selectedText.trim()) return;
      const escapedText = selectedText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
      const reg = new RegExp(escapedText, 'g');
      editArea.innerHTML = originEditContent.replace(reg, '<span class="highlight">$&</span>');
      contentDiv.innerHTML = originDivContent.replace(reg, '<span class="highlight">$&</span>');
    }

    // 监听两个区域的选中事件
    [editArea, contentDiv].forEach(el => {
      el.addEventListener('mouseup', function() {
        const selection = window.getSelection ? window.getSelection() : document.getSelection();
        const selected = selection.toString();
        highlightBoth(selected);
      });
      // 内容同步
      el.addEventListener('input', function() {
        const newContent = this.innerText;
        originEditContent = newContent;
        originDivContent = newContent;
        editArea.innerText = newContent;
        contentDiv.innerText = newContent;
      });
    });

    // 点击空白清除高亮
    document.addEventListener('click', function(e) {
      if (e.target !== editArea && e.target !== contentDiv && !contentDiv.contains(e.target) && !editArea.contains(e.target)) {
        clearAllHighlight();
      }
    });
  </script>
</body>
</html>

内容的提问来源于stack exchange,提问作者Ivan Dern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:54:07