如何限制TinyMCE编辑器中的空白行数?
限制TinyMCE编辑器内文本前后空白行数的实现方案
需求背景
要求编辑器内文本的前后最多保留两行空白,无论用户通过Enter(生成空<p>标签)还是Shift+Enter(生成<br>元素)输入空白。
已完成的基础处理
已通过正则解决了部分场景:
- 将连续4个及以上的
<br>替换为3个(对应2行空白):
// 将4个及以上<br>替换为3个<br> var updatedContent = content.replace(/((<br\s*\/?>\s*){4,})/gm, '<br><br><br>');
- 类似地,将连续3个及以上的空
<p>标签替换为2个。
同时处理了<p>标签开头直接出现3个及以上<br>的情况,将其限制为2个<br>,避免生成超过2行的空白。
注意:TinyMCE会自动将内容包裹在<p>标签内,尝试将空<p></p>替换为<br>会被自动转换为<p><br></p>,与原空标签效果一致,因此无法彻底清除空<p>。
待解决的复杂混合场景
以下包含空<p>和带<br>的<p>的混合场景,现有正则无法正确处理:
<p>text<br><br></p> <p><br><br></p> <p>Before this text, there are three blank lines; the allowed maximum is two<br><br></p> <p><br><br>Text with three blank lines before</p> <p></p> <p></p> <p><br><br>This is text with four blank lines before<br></p> <p> "<br>" right in front of "</p>" doesn't have any effect on blank lines</p> <p><br><br></p> <p></p> <p>Before this text, there are three blank lines; the allowed maximum is two<br></p>
解决方案
思路:分阶段处理空白结构
先处理单个<p>内部的<br>,再处理连续的空<p>块,最后合并内容确保空白行数不超过限制。
1. 完整处理函数实现
function limitBlankLines(content) { // 处理单个<p>内的连续<br>,最多保留3个(对应2行空白) content = content.replace(/((<br\s*\/?>\s*){4,})/gm, '<br><br><br>'); // 限制<p>开头的连续<br>最多3个 content = content.replace(/(<p>\s*)(<br\s*\/?>\s*){3,}/gm, '$1<br><br><br>'); // 限制<p>结尾的连续<br>最多3个 content = content.replace(/(<br\s*\/?>\s*){3,}(\s*<\/p>)/gm, '<br><br><br>$2'); // 匹配所有空<p>标签(包括空的、仅含空白和<br>的) const emptyPRegex = /<p>\s*(<br\s*\/?>\s*)*<\/p>/gm; // 替换连续3个及以上的空<p>为2个 content = content.replace(/(<p>\s*(<br\s*\/?>\s*)*<\/p>\s*){3,}/gm, '<p><br></p><p><br></p>'); // 处理混合场景:拆分内容块,限制连续空白块数量 const blocks = content.split(/(<p>\s*(<br\s*\/?>\s*)*<\/p>)/gm).filter(block => block.trim() !== ''); let result = ''; let consecutiveEmptyBlocks = 0; for (const block of blocks) { const isEmpty = emptyPRegex.test(block); if (isEmpty) { consecutiveEmptyBlocks++; if (consecutiveEmptyBlocks <= 2) { result += block; } } else { consecutiveEmptyBlocks = 0; result += block; } } return result; }
2. 集成到TinyMCE
通过编辑器事件实时处理内容,确保输入时自动限制空白行数:
tinymce.init({ selector: 'textarea', setup: function(editor) { // 内容变更时处理 editor.on('Change', function() { const processed = limitBlankLines(editor.getContent()); editor.setContent(processed); }); // 按下Enter/Shift+Enter时实时处理 editor.on('KeyUp', function(e) { if (e.key === 'Enter') { setTimeout(() => { const processed = limitBlankLines(editor.getContent()); editor.setContent(processed); }, 100); // 延迟确保TinyMCE完成DOM生成 } }); } });
TinyMCE替代方案
如果不想用正则,可尝试使用TinyMCE的content_style配置隐藏多余空白,但效果不如直接处理内容可靠;或使用content_filter插件自定义过滤规则,不过事件监听的方式更直观可控。
内容的提问来源于stack exchange,提问作者MaN8fy
相关产品推荐
相关产品推荐

