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>标签的列表项的处理逻辑:
- 在执行缩进操作前,先检查当前选中的列表项是否包含
<p>子元素 - 如果包含,先把
<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
相关产品推荐
相关产品推荐

