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

CKEditor 4.2含<p>标签列表项点击增加缩进内容丢失问题

解决CKEditor 4.2中含<p>标签的列表项缩进时内容丢失的问题

我之前维护老项目时也碰到过CKEditor 4.2这个糟心的bug——当列表项(<li>)里嵌套了段落标签(<p>)时,点击「增加缩进」会直接把整个列表内容清空,尤其是带起始序号的有序列表更容易触发这个问题。

问题根源

CKEditor 4.2的列表处理模块在处理嵌套列表缩进时,没有正确识别包含块级元素(比如<p>)的列表项结构。执行缩进命令时,它会错误判定这类列表项的结构不符合预期,进而错误移除整个列表的内容。

可复现的测试代码

<ol start="7">
  <li>
    <p>This LI contains P tag</p>
  </li>
  <li>This lis is without P tag</li>
  <li>Hardcopy Options:
    <ul>
      <li>The report is only emailed.</li>
    </ul>
  </li>
</ol>

选中第一个带<p>标签的列表项,点击「增加缩进」就会触发内容丢失的问题。

解决方案(因无法升级版本,提供两种可行方案)

方案1:修改CKEditor列表插件核心逻辑

找到CKEditor安装目录下的plugins/list/plugin.js文件,定位到处理列表缩进的indentList相关函数,调整它对含<p>标签的列表项的处理逻辑:

  1. 在执行缩进操作前,先检查当前选中的列表项是否包含<p>子元素
  2. 如果包含,先把<p>里的内容提取出来,替换掉原列表项的内容,再执行缩进

示例修改片段:

// 找到处理缩进命令的代码块,添加前置处理逻辑
editor.on('beforeCommandExec', function(event) {
  if (event.data.name === 'indentlist') {
    var sel = editor.getSelection();
    var startEl = sel.getStartElement();
    var liEl = startEl.getAscendant('li', true);
    
    if (liEl && liEl.getFirst() && liEl.getFirst().is('p')) {
      // 提取<p>标签内的内容,替换<li>的内容
      var pContent = liEl.getFirst().getHtml();
      liEl.setHtml(pContent);
    }
  }
});

修改后保存插件文件,清空浏览器缓存后重新加载编辑器,就能避免缩进时内容丢失的问题。

方案2:内容预处理(临时 workaround)

如果不想修改CKEditor核心代码,可以在内容加载到编辑器之前,先移除列表项里的<p>标签:

// 在编辑器初始化完成后,加载内容前执行预处理
editor.on('instanceReady', function() {
  var originalContent = editor.getData();
  // 正则替换掉<li>内的<p>标签
  var processedContent = originalContent.replace(/<li>\s*<p>(.*?)<\/p>\s*<\/li>/gi, '<li>$1</li>');
  editor.setData(processedContent);
});

这个方法的好处是不用修改核心插件,但会丢失<p>标签带来的样式,适合对段落样式要求不高的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:50:20