如何强制CKEditor保留<br>标签?

4
我正在使用最新版本的CKEditor(截至目前为止是4.7)标准软件包,我希望能够强制保留换行符元素(<br>)。
我尝试使用以下配置,但均未成功:
CKEDITOR.replace('ck', {
    allowedContent: true,
    enterMode: CKEDITOR.ENTER_BR
});

你可以在这个 jsfiddle中看到,当你打开“源代码”模式时,<br> 标签会被替换成一个 &nbsp;
如何实现这一效果?

您提供的小提琴将替换任何存在于div之外的断行标签为空。这会使这些标签看起来被替换为&nbsp;。如果您清空编辑器,添加相同的文本并单击“源”,它将显示<br>标记已被保留。为了保留<br>标记,它们必须是<div>的子元素。您的应用程序是否可以反映这一点? - Joseph Marikle
很不幸,我无法控制加载到我的CKEditor中的内容。这些内容是由我的客户发送的,然后加载到CKEditor中,他期望能够得到他的格式化内容... - Gyum Fox
检查一下,我认为这会对你有帮助:http://ckeditor.com/forums/Support/trying-use-br-instead-p - Yassine CHABLI
@MOHAMMEDYASSINEChabli 我已经在使用这个配置了。br标签被使用,这不是问题所在。问题在于CKEditor会删除一些br标签并将它们替换为&nbsp; - Gyum Fox
你是在简单的HTML中使用CKEditor还是模板引擎? - Yassine CHABLI
@MOHAMMEDYASSINEChabli,请查看问题中的JS fiddle,没有什么特别的:只是将最新的CKEditor添加到一个空白页面中。 - Gyum Fox
3个回答

3

在这个CKEditor ticket上提供了一个解决方法(或者至少是部分解决方法),它可以强制CKEditor保留<br>标签:

editor.on( 'pluginsLoaded', function( evt ){
    evt.editor.dataProcessor.dataFilter.addRules({
        elements :{
            br : function( element ) {          
                //if next element is BR or <!--cke_br_comment-->, ignore it.
                if( element && element.next && ( element.next.name == 'br' || element.next.value == 'cke_br_comment' ) ){
                    return;
                }else {
                    var comment = new CKEDITOR.htmlParser.comment( 'cke_br_comment' );
                    comment.insertAfter( element ); 
                }
            }
        }
    });

evt.editor.dataProcessor.htmlFilter.addRules({
    comment : function( value, node ) {
        if( value.indexOf('cke_br_comment') >= 0 ) {
            return false;
        }
    }
});

这里是更新后的示例代码

编辑:你可能还想查看我的其他答案,根据你的需求,它可能更适合你。


2

我认为我找到了一个更好的答案,可以在更多情况下使用:引入"brangel"插件:

CKEDITOR.plugins.add('brangel', {
    init: function (editor) {
        editor.on('toHtml', function( evt ) {
            protectBRs(evt.data.dataValue);
        }, null, null, 5);
        editor.on('toHtml', function( evt ) {
            unprotectBRs(evt.data.dataValue);
        }, null, null, 14);
        editor.on('toDataFormat', function( evt ) {
            protectBRs(evt.data.dataValue);
        }, null, null, 5);
        editor.on('toDataFormat', function( evt ) {
            unprotectBRs(evt.data.dataValue);
        }, null, null, 14);

        function protectBRs(element) {
            var children = element.children;
            if (children) {
                for (var i = children.length; i--; ) {
                    var child = children[i];
                    if (child.name == "br") {
                        var placeholder = new CKEDITOR.htmlParser.text('{cke_br}');
                        placeholder.insertAfter(child);
                        child.remove();
                    } else {
                        protectBRs(child);
                    }
                }
            }
        }

        function unprotectBRs(element) {
            var children = element.children;
            if (children) {
                for (var i = children.length; i--; ) {
                    var child = children[i];
                    if (child instanceof CKEDITOR.htmlParser.text && child.value === "{cke_br}") {
                        var br = new CKEDITOR.htmlParser.element('br');
                        br.insertAfter(child);
                        child.remove();
                    } else {
                        unprotectBRs(child);
                    }
                }
            }
        }
    }
});

这个想法是为了避免在CKEditor过滤期间 (toDataFormattoHtml 事件) 销毁 <br> 元素,而是将它们暂时替换成一些占位文本 ({cke_br}),最后再将它们恢复过来。这对用户来说是透明的。

这里更新了fiddle示例


1
据报道,CKeditor的开发人员表示,br to nbsp自动转换不是问题,但是CKeditor的规范化方式可能会有问题。这不会给您带来任何问题,因此您不必担心您的br标记被转换为nbsp。请查看以下链接获取更多信息。
如果您希望从源代码中删除&nbsp,则一种方法是包含以下内容:
 basicEntities: false,
 entities_additional: 'lt,gt,amp,apos,quot'

我理解这个问题并不算大,因为输出看起来是一样的。然而,如果考虑到消息可能会通过第三方工具进行解析/还原,这可能会成为一个问题。建议您更新您的回答,并尝试其中一个与您提供给我的链接相关的解决方法。 - Gyum Fox
提示:http://dev.ckeditor.com/ticket/10146#comment:34 看起来效果不错。请参考更新后的fiddle:https://jsfiddle.net/922tL76e/3/。如果您想获得奖励,请随时更新您的答案。 - Gyum Fox
如果你想避免   本身,你可以简单地使用 basicEntities: false。 - Ozesh
无论是&nbsp还是空格都没有关系,我想要保留BR。没关系,我会根据您给我的票据中提供的解决方法得到答案。 - Gyum Fox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接