如何为具有不同高度的多个实例设置CKEditor

How to set up CKEditor for multiple instances with different heights?

本文关键字:实例 CKEditor 设置 高度      更新时间:2023-09-26

我希望有多个基于相同配置设置但高度不同的CKEditor实例。我尝试用默认高度设置config,设置第一个实例,然后覆盖高度&设置第二个实例:

var config = {
    .....
    height:'400'
};
$('#editor1').ckeditor(config);
config.height = '100';
$('#editor2').ckeditor(config);

但我得到了两个CKEditor实例,它们都有100px的高度。

我也试过这个:

CKEDITOR.replace('editor2',{
    height: '100'
});

我收到了该实例已经存在的错误消息。我四处搜索了一下&发现有人在类似的情况下得到了建议,你必须在替换((之前销毁((实例,但这对于仅仅设置一个不同的初始高度来说似乎太复杂了。

最后我设置了两个不同的配置&复制到工具栏上_Full属性:

var config1 = {
    height:'400',
    startupOutlineBlocks:true,
    scayt_autoStartup:true,
    toolbar_Full:[
        { name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
        { name: 'editing', items : [ 'Find','Replace','-' ] },
        { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
        { name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] },
        '/',
        { name: 'links', items : [ 'Link','Unlink','Anchor' ] },
        { name: 'insert', items : [ 'Image','HorizontalRule' ] },
        { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },
        { name: 'colors', items : [ 'TextColor','BGColor' ] },
        { name: 'tools', items : [ 'Maximize', 'ShowBlocks' ] },
        { name: 'document', items : [ 'Source' ] }
    ]
}
var config2 = {
    height:'100',
    startupOutlineBlocks:true,
    scayt_autoStartup:true
};
config2.toolbar_Full = config1.toolbar_Full;
$('#editor1').ckeditor(config1);
$('#editor2').ckeditor(config2);

有更好的方法吗?我缺了什么吗?有这个问题,但他们没有发布足够有用的帖子,&这个非常相似的问题还没有得到回答。谢谢

更新:

这似乎是CKEditor的定时/配置处理怪癖——配置是read&稍后应用(我猜是在编辑器的DOM框架设置好之后(,而不是在编辑器第一次实例化时应用。

因此,在第一个编辑器用.ceditor((实例化后,立即对配置设置所做的任何更改都将在接下来几毫秒内的某个时间点由编辑器实际应用。我认为这不是正常的行为,也不符合逻辑。

例如,在我的第一个示例中,您可以通过使用setTimeout((延迟第二个CKEditor实例来获得预期的行为(在第一个编辑器实例化后覆盖config.height属性(。Firefox需要约100毫秒,IE需要1毫秒。Wacky&错误的

CKEditor应该在第一次实例化每个编辑器时读取配置设置。现在,每个人都必须围绕这个怪癖工作。

用自定义高度初始化两个编辑器的最简单方法是:

$('#editor1').ckeditor({ height: 100 });
$('#editor2').ckeditor({ height: 200 });

或不带jQuery:

CKEDITOR.replace('editor1', { height: 100 });
CKEDITOR.replace('editor2', { height: 200 });

AFAIK不可能随时更改编辑的高度。

如果这些方法对你不起作用,那么你做错了什么。

更新:

回答你的评论-事实上,你的问题不是关于CKEditor,而是关于共享一个只有两个不同属性的对象。所以你可以这样尝试:

var configShared = {
        startupOutlineBlocks:true,
        scayt_autoStartup:true,
        // etc.
    },
    config1 = CKEDITOR.tools.prototypedCopy(configShared),
    config2 = CKEDITOR.tools.prototypedCopy(configShared);
config1.height = 100;
config2.height = 200;
CKEDITOR.replace('editor1', config1);
CKEDITOR.replace('editor2', config2);

CKEDITOR.tools.prototypedCopy是一个创建新对象的工具,其原型设置为传递的原型。因此,它们共享除您稍后覆盖的属性之外的所有属性。

更新2:

这是问题中"更新"部分的更新:(。

CKEditor的时间安排或bug或其他任何东西都没有什么奇怪之处——它是纯JavaScript以及BOM/DOM和浏览器的工作方式,加上一些实用的方法。

首先,90%的BOM/DOM是同步的,但也有一些事情不是同步的。因此,整个编辑器必须具有异步性。这就是为什么它提供了这么多活动。

第二件事-在JS对象中是通过引用传递的,因为我们希望CKEditor能够非常快速地初始化,所以我们应该避免不必要的任务。其中之一是复制配置对象(没有充分的理由(。因此,为了节省一些毫秒(并且由于异步插件也在加载(,CKEditor仅通过将其原型设置为包含默认选项的对象来扩展传递的配置对象。

总结-我知道这可能看起来像一个bug,但这就是JS/BOM/DOM库的工作方式。我确信许多其他库的异步方法也受到了同样的问题的影响。

添加此项,您将在单页中获得两个CKeditor的不同工具栏

Reinmar的
<script>
    CKEDITOR.on('instanceCreated', function (event) {
        var editor = event.editor,
            element = editor.element;
        if (element.is('h1', 'h2', 'h3') || element.getAttribute('id') == 'editorTitle') {
            editor.on('configLoaded', function () {
                // Remove unnecessary plugins to make the editor simpler.
                editor.config.removePlugins = 'find,flash,' +
                    'forms,iframe,image,newpage,removeformat,' +
                    'smiley,specialchar,stylescombo,templates';
                // Rearrange the layout of the toolbar.
                editor.config.toolbarGroups = [
                    { name: 'editing', groups: ['basicstyles'] },
                    { name: 'undo' },
                    //{ name: 'clipboard', groups: ['selection', 'clipboard'] },
                  { name: 'styles' },
                    { name: 'colors' },
                    { name: 'tools' }
                  //  { name: 'about' }
                ];
            });
        }
    });
</script>

上面的解决方案对我有效,但我决定再提供一个之前使用的解决方案。

这真的很简单,您只需要知道,ckeditor为每个id几乎相同的实例创建content-div元素,唯一的区别是增量值。所以,若你们有2,3,4…个实例,唯一的区别就是序数。代码在这里:

    CKEDITOR.on('instanceReady', function(){
    $('#cke_1_contents').css('height','200px');
}); 

该事件将为您拥有的每个实例激活,因此,如果您想为所有实例设置高度,您可以创建全局变量并像#cke_"+x+"contents中的x一样使用它,每次激活事件时,将x增加为1,检查行中的哪个实例具有简单的if,然后设置高度。

    var x=1;
CKEDITOR.on('instanceReady', function(){
    if(x==1) h='200px';
    else if(x==2)h='400px';
    else if(x==3)h='700px';
    $('#cke_'+x+'_contents').css('height',h);
    x++;
}); 

这不是最好的解决方案,但它正在发挥作用,问题是您实际上看到了内容div的大小调整。

2019年6月25日更新。

请使用此代码添加多个CKEditor实例,每个实例具有自定义高度。有史以来最简单的方式。

  <textarea name="editor1" style="height:30px;" class="ckeditor"></textarea>
   <script type="text/javascript">
      CKEDITOR.replace( 'editor1' );
      CKEDITOR.add            
   </script>
<textarea name="editor2" style="height:40px;" class="ckeditor"></textarea>
   <script type="text/javascript">
      CKEDITOR.replace( 'editor2' );
      CKEDITOR.add            
   </script>
<textarea name="editor3" style="height:50px;" class="ckeditor"></textarea>
   <script type="text/javascript">
      CKEDITOR.replace( 'editor3' );
      CKEDITOR.add            
   </script>
<textarea name="editor4" style="height:60px;" class="ckeditor"></textarea>
   <script type="text/javascript">
      CKEDITOR.replace( 'editor4' );
      CKEDITOR.add            
   </script>
<textarea name="editor5" style="height:70px;" class="ckeditor"></textarea>
   <script type="text/javascript">
      CKEDITOR.replace( 'editor5' );
      CKEDITOR.add            
   </script>

参考:此处

如果您多次将ckeditor.js添加到页面中,可能会导致该问题。脚本代码必须在每一页中定义一次。<script type="text/javascript" src="Fck342/ckeditor.js"></script>

只需使用CKEDITOR.replaceAll();