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条回答
可以哭但决不认输i
2楼-- · 2020-01-24 20:07
function loadEditor(id)
{
    var instance = CKEDITOR.instances[id];
    if(instance)
    {
        CKEDITOR.remove(instance);
    }
    CKEDITOR.replace(id);
}
查看更多
贪生不怕死
3楼-- · 2020-01-24 20:14

I've prepared my own solution based on all above codes.

      $("textarea.ckeditor")
      .each(function () {

                var editorId = $(this).attr("id");

                try {    
                    var instance = CKEDITOR.instances[editorId];
                    if (instance) { instance.destroy(true); }

                }
                catch(e) {}
                finally {
                    CKEDITOR.replace(editorId);
                }
            });

It works perfectly for me.

Sometimes after AJAX request there is wrong DOM structure. For instace:

<div id="result">
   <div id="result>
   //CONTENT
   </div>
</div>

This will cause issue as well, and ckEditor will not work. So make sure that you have correct DOM structure.

查看更多
狗以群分
4楼-- · 2020-01-24 20:16

For this to work you need to pass boolean parameter true when destroying instance:

    var editor = CKEDITOR.instances[name];
    if (editor) { editor.destroy(true); }
    CKEDITOR.replace(name);
查看更多
The star\"
5楼-- · 2020-01-24 20:16

Perhaps this will help you out - I've done something similar using jquery, except I'm loading up an unknown number of ckeditor objects. It took my a while to stumble onto this - it's not clear in the documentation.

function loadEditors() {
    var $editors = $("textarea.ckeditor");
    if ($editors.length) {
        $editors.each(function() {
            var editorID = $(this).attr("id");
            var instance = CKEDITOR.instances[editorID];
            if (instance) { instance.destroy(true); }
            CKEDITOR.replace(editorID);
        });
    }
}

And here is what I run to get the content from the editors:

    var $editors = $("textarea.ckeditor");
    if ($editors.length) {
        $editors.each(function() {
            var instance = CKEDITOR.instances[$(this).attr("id")];
            if (instance) { $(this).val(instance.getData()); }
        });
    }

UPDATE: I've changed my answer to use the correct method - which is .destroy(). .remove() is meant to be internal, and was improperly documented at one point.

查看更多
地球回转人心会变
6楼-- · 2020-01-24 20:17

Its pretty simple. In my case, I ran the below jquery method that will destroy ckeditor instances during a page load. This did the trick and resolved the issue -

JQuery method -

function resetCkEditorsOnLoad(){

    for(var i in CKEDITOR.instances) {
        editor = CKEDITOR.instances[i];
            editor.destroy();
            editor = null;
    }
}

$(function() {

            $(".form-button").button();
    $(".button").button();

    resetCkEditorsOnLoad(); // CALLING THE METHOD DURING THE PAGE LOAD

            .... blah.. blah.. blah.... // REST OF YOUR BUSINESS LOGIC GOES HERE

       });

That's it. I hope it helps you.

Cheers, Sirish.

查看更多
不美不萌又怎样
7楼-- · 2020-01-24 20:18

You can remove any ckeditor instance by remove method of ckeditor. Instance will be id or name of the textarea.

if (CKEDITOR.instances[instance_name]) {
    CKEDITOR.remove(CKEDITOR.instances[instance_name]);
}
查看更多
登录 后发表回答