CKEditor instance already exists

2020-01-24 19:42发布

I am using jquery dialogs to present forms (fetched via AJAX). On some forms I am using a CKEditor for the textareas. The editor displays fine on the first load.

When the user cancels the dialog, I am removing the contents so that they are loaded fresh on a later request. The issue is, once the dialog is reloaded, the CKEditor claims the editor already exists.

uncaught exception: [CKEDITOR.editor] The instance "textarea_name" already exists.

The API includes a method for destroying existing editors, and I have seen people claiming this is a solution:

if (CKEDITOR.instances['textarea_name']) {
CKEDITOR.instances['textarea_name'].destroy();
}
CKEDITOR.replace('textarea_name');

This is not working for me, as I receive a new error instead:

TypeError: Result of expression 'i.contentWindow' [null] is not an object.

This error seems to occur on the "destroy()" rather than the "replace()". Has anyone experienced this and found a different solution?

Is is possible to 're-render' the existing editor, rather than destroying and replacing it?

UPDATED Here is another question dealing with the same problem, but he has provided a downloadable test case.

30条回答
We Are One
2楼-- · 2020-01-24 19:51

This functions works for me in CKEditor version 4.4.5, it does not have any memory leaks

 function CKEditor_Render(CkEditor_id) {
        var instance = CKEDITOR.instances[CkEditor_id];
        if (CKEDITOR.instances.instance) {
            CKEDITOR.instances.instance.destroy();
        }
        CKEDITOR.replace(CkEditor_id);
    }

// call this function as below

var id = 'ckeditor'; // Id of your textarea

CKEditor_Render(id);
查看更多
别忘想泡老子
3楼-- · 2020-01-24 19:53
CKEDITOR.instances = new Array();

I am using this before my calls to create an instance (ones per page load). Not sure how this affects memory handling and what not. This would only work if you wanted to replace all of the instances on a page.

查看更多
Explosion°爆炸
4楼-- · 2020-01-24 19:53

I hade the same problem with a jQuery Dialog.

Why destroy the instance if you just want to remove previous data ?

function clearEditor(id)
{
  var instance = CKEDITOR.instances[id];
  if(instance)
  {
    instance.setData( '' );
  }
}
查看更多
等我变得足够好
5楼-- · 2020-01-24 19:54

i had the same problem with instances, i was looking everywhere and finally this implementation works for me:



    //set my instance id on a variable

    myinstance = CKEDITOR.instances['info'];

    //check if my instance already exist

    if (myinstance) { 
        CKEDITOR.remove(info)
    }

    //call ckeditor again

    $('#info').ckeditor({
        toolbar: 'Basic',
        entities: false,
        basicEntities: false
    });

查看更多
聊天终结者
6楼-- · 2020-01-24 19:54

To support dynamic (Ajax) loading of forms (without page refreshes between) which contain textareas with the same (same form is called again) or different ID's (previously unloaded form) and convert them to CKEditor elements I did the following (using the JQuery adapter):

After the page has finished every Ajax call that delivers a textarea to be converted, I make a call to the following function:

setupCKeditor()

This looks like this (it assumes your textareas to be converted to RTE's have class="yourCKClass"):

    /* Turns textAreas into TinyMCE Rich Text Editors where
 * class: tinymce applied to textarea.
 */
function setupCKeditor(){

    // define editor configuration      
    var config = {skin : 'kama'};

    // Remove and recreate any existing CKEditor instances
    var count = 0;
    if (CKEDITOR.instances !== 'undefined') {
        for(var i in CKEDITOR.instances) {

            var oEditor   = CKEDITOR.instances[i];
            var editorName = oEditor.name;

             // Get the editor data.
            var data = $('#'+editorName).val();

            // Check if current instance in loop is the same as the textarea on current page
            if ($('textarea.yourCKClass').attr('id') == editorName) {
                if(CKEDITOR.instances[editorName]) {

                    // delete and recreate the editor
                    delete CKEDITOR.instances[editorName];
                    $('#'+editorName).ckeditor(function() { },config);
                    count++;

                }
            }   


        }
    }

    // If no editor's exist in the DOM, create any that are needed.             
    if (count == 0){

        $('textarea.yourCKClass').each( function(index) {

                var editorName = $(this).attr('id');
                $('#'+editorName).ckeditor(function() { $('#'+editorName).val(data); },config);

            });

    }


}

I should mention that the line:

$('#'+editorName).ckeditor(function() { $('#'+editorName).val(data); },config);

could (and should) be simply:

$('#'+editorName).ckeditor(function() { },config);

however I found that the editor would often show the correct content for a second after loading and them empty the editor of the desired content. So that line with the callback code forces the CKEditor content to be the same as the originating textarea content. Causes a flicker when used. If you can avoid using it, do so..

查看更多
在下西门庆
7楼-- · 2020-01-24 19:55

I had this problem too, but I solved it in a much simpler way...

I was using the class "ckeditor" in my jQuery script as the selector for which textareas I wanted use for CKEditor. The default ckeditor JS script also uses this class to identify which textareas to use for CKEditor.

This meant there is a conflict between my jQuery script and the default ckeditor script.

I simply changed the class of the textarea and my jQuery script to 'do_ckeditor'(you could use anything except "ckeditor") and it worked.

查看更多
登录 后发表回答