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

自定义WYSIWYG编辑器选中文本保持选中状态时如何移除文本格式

自定义WYSIWYG编辑器保持选中状态切换格式实现方案

问题成因

现有逻辑核心缺陷为DOM修改后未主动同步更新选区范围:

  1. 首次点击格式按钮插入STRONG/EM标签后,选区仍停留在原文本节点位置,未指向新插入的格式标签。第二次点击时获取的commonAncestorContainer.parentElement仍为外层段落标签,无法进入「已存在对应格式则移除」的判断分支
  2. 移除格式替换为纯文本节点后未更新选区,会出现选区丢失、后续操作失效问题
  3. 直接读取commonAncestorContainer.parentElement判断格式的逻辑鲁棒性不足,跨节点选中文本时易出现判断错误。

修复后完整代码

JavaScript 逻辑

document.getElementById('bold').addEventListener('click', () => edit('STRONG'));
document.getElementById('italic').addEventListener('click', () => edit('EM'));

function edit(format) {
  const selection = document.getSelection();
  if (!selection.rangeCount) return;
  const range = selection.getRangeAt(0);
  // 兼容文本节点、元素节点两种场景获取父元素
  const parentElement = range.commonAncestorContainer.nodeType === 3 
    ? range.commonAncestorContainer.parentElement 
    : range.commonAncestorContainer;

  // 已应用对应格式:执行移除
  if (parentElement.tagName === format) {
    const grandParent = parentElement.parentElement;
    const textNode = document.createTextNode(parentElement.textContent);
    grandParent.insertBefore(textNode, parentElement);
    grandParent.removeChild(parentElement);
    grandParent.normalize();

    // 重新设置选区到替换后的纯文本节点
    const newRange = document.createRange();
    newRange.selectNodeContents(textNode);
    selection.removeAllRanges();
    selection.addRange(newRange);
    return;
  }

  // 未应用对应格式:执行添加
  const formatNode = document.createElement(format);
  const fragment = range.extractContents();
  formatNode.appendChild(fragment);
  range.insertNode(formatNode);

  // 重新设置选区到新插入的格式节点
  const newRange = document.createRange();
  newRange.selectNodeContents(formatNode);
  selection.removeAllRanges();
  selection.addRange(newRange);
}

HTML 结构

<button id="bold">B</button>
<button id="italic">I</button>

<p>Lorem ipsum</p>

关键改动点

  • 新增选区存在性判断,兼容无选中内容、编辑器未聚焦的边界场景
  • 修正父元素获取逻辑,同时兼容当前锚点为文本节点、元素节点两种情况
  • 每次添加/移除格式的DOM操作完成后,主动创建新的Range实例选中操作后的目标节点内容,重新绑定到选区,保证连续点击按钮时选区始终落在正确节点上,可正常触发格式移除逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:06:23