CKEditor回车后字符计数异常:部分场景计数为2而非1的原因
CKEditor字符计数异常:标点后按Enter计数加2的原因分析
问题场景
使用以下代码实现CKEditor字符计数功能时,发现在句号、感叹号等标点后按下Enter键,字符计数会增加2,而非预期的1:
var editorConfig = { height: '400px', filebrowserUploadMethod: "form", filebrowserUploadUrl: "main_blog_upload.php", defaultLanguage: "es", language: "es", enterMode: CKEDITOR.ENTER_BR, // Set to use <br> tags for line breaks shiftEnterMode: CKEDITOR.ENTER_BR, // Set to use <br> tags for Shift+Enter charCountCallback: function(charCount) { // Get the data from the editor var data = this.getData(); // Calculate the number of line breaks (only <br> tags are used) var lineBreaksCount = (data.match(/<br[^>]*>/g) || []).length; // Calculate the character count, excluding line breaks var characterCount = data.replace(/<[^>]*>/g, '').length; // Add the character count and line breaks count return characterCount + lineBreaksCount; } }; // Create CKEditor instance with the merged configuration var editor = CKEDITOR.replace('editor', editorConfig); function stripHtml(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; } function countWordsAndCharacters() { var data = editor.getData(); var div = document.createElement('div'); div.innerHTML = data; var textOnly = div.textContent || div.innerText || ''; // Check if textOnly is empty or contains only white spaces var wordsArray = textOnly.trim().split(/\s+/); var wordCount = (wordsArray.length === 1 && wordsArray[0] === '') ? 0 : wordsArray.length; // var characterCount = textOnly.replace(/\s/g, '').length; var characterCount = textOnly.length; $('#count').text(`${wordCount} words ${characterCount} characters`); } editor.on('instanceReady', () => { countWordsAndCharacters(); }); editor.on('keyup', () => { countWordsAndCharacters(); }); editor.on('change', () => { countWordsAndCharacters(); }); editor.on('key', function(event) { var enterKey = 13; if (event.data.keyCode === enterKey) { var selection = editor.getSelection(); var ranges = selection.getRanges(); var range = ranges[0]; var blockTag = range.startContainer.getAscendant('p', true); if (blockTag && range.checkStartOfBlock() && range.checkEndOfBlock()) { // Prevent CKEditor default Enter key behavior event.cancel(); // Insert <br> tag manually var brElement = new CKEDITOR.dom.element('br'); editor.editable().insertElement(brElement); } } });
异常测试案例:
- 按下Enter后计数加2的句子:
Las aplicaciones de aprendizaje de idiomas están disponibles en línea y ofrecen una amplia variedad de recursos de aprendizaje, desde lecciones interactivas hasta clases en vivo con profesores nativos de inglés.En este artículo, hemos reunido las 12 mejores aplicaciones para aprender inglés, que pueden ser usadas tanto por niños como por adultos (¡algunas más que otras!) - 按下Enter后计数加1的句子:
Cada una de estas aplicaciones ha sido cuidadosamente seleccionada para brindarte una experiencia de aprendizaje única y efectiva.
原因分析
问题源于CKEditor自动空格插入机制与计数逻辑的冲突:
编辑器自动格式化:当光标位于标点符号(
.、!等)之后时,CKEditor的默认自动排版规则会自动插入一个空格,用于优化文本间距。此时按下Enter键,编辑器会先完成这个自动空格插入,再执行你自定义的<br>插入逻辑。计数逻辑的统计规则:你的
countWordsAndCharacters函数直接以textOnly.length统计字符数,这个长度包含了编辑器自动插入的空格,再加上<br>标签转换后的换行符(对应文本中的1个换行字符),最终总计数就会增加2(1个自动空格 + 1个换行符)。第三个句子正常的原因:如果该句子末尾的标点后没有触发自动空格插入(可能是光标位置未命中自动格式化的触发条件),按下Enter只会插入换行符,因此计数仅增加1。
另外,你自定义的Enter键处理逻辑仅覆盖了光标在空<p>块首尾的场景,未处理光标在文本末尾(标点后)的情况,导致编辑器的自动空格插入逻辑仍会生效,产生额外的统计字符。
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

