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

如何在输入时实时修改contenteditable div中特定字符的颜色

实现方案

你之前踩坑的核心原因是选择了按键监听的方案,天生存在兼容性、场景覆盖不全的问题,换下面的思路可以完美解决需求:

  • 用input事件替代keyup/keypress监听:input事件会在contenteditable元素内容发生任何变化时触发,不管是键盘输入、粘贴、剪切操作都能捕获,也不需要处理按键码、键盘布局匹配的问题。
  • 用正则匹配替换目标字符:每次内容变化时,用正则匹配所有[、]、/字符,替换为带自定义样式的<span>包裹,实现指定颜色渲染。
  • 手动保存恢复光标位置:修改innerHTML会导致浏览器重置光标位置到内容开头,所以替换内容前要先记录当前光标的偏移量,替换完成后手动将光标复位到之前的位置,避免后续输入内容误入样式span内。

可运行示例代码

首先定义样式:

.highlight {
  color: #f00;
}

JS逻辑(基于jQuery,和你现有代码适配):

$(function() {
  const $inputDiv = $("#inputDiv");
  // 记录光标位置的工具方法
  function getCaretOffset(element) {
    const sel = window.getSelection();
    if (sel.rangeCount === 0) return 0;
    const range = sel.getRangeAt(0);
    const preRange = range.cloneRange();
    preRange.selectNodeContents(element);
    preRange.setEnd(range.endContainer, range.endOffset);
    return preRange.toString().length;
  }
  // 恢复光标位置的工具方法
  function setCaretOffset(element, offset) {
    const sel = window.getSelection();
    const range = document.createRange();
    range.selectNodeContents(element);
    const nodeStack = [element], charCount = 0, stop = false;
    let node;
    while (nodeStack.length && !stop) {
      node = nodeStack.pop();
      if (node.nodeType === 3) {
        const nextCharCount = charCount + node.length;
        if (offset >= charCount && offset <= nextCharCount) {
          range.setStart(node, offset - charCount);
          range.collapse(true);
          stop = true;
        }
        charCount = nextCharCount;
      } else {
        let i = node.childNodes.length;
        while (i--) nodeStack.push(node.childNodes[i]);
      }
    }
    sel.removeAllRanges();
    sel.addRange(range);
  }
  // 监听内容变化
  $inputDiv.on('input', function() {
    // 先保存当前光标偏移
    const caretOffset = getCaretOffset(this);
    // 替换目标字符,注意正则转义
    this.innerHTML = this.textContent.replace(/([\[\]\/])/g, '<span class="highlight">$1</span>');
    // 恢复光标位置
    setCaretOffset(this, caretOffset);
  });
});

方案优势

  • 完全不需要处理按键码,不存在不同键盘布局的兼容性问题,输入、粘贴场景下都能正常匹配字符上色。
  • 光标位置自动恢复,不会出现后续输入内容继承样式的问题,也不会出现重复字符的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:45:03