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条回答
Ridiculous、
2楼-- · 2020-01-24 19:59

This is what worked for me:

for(name in CKEDITOR.instances)
{
  CKEDITOR.instances[name].destroy()
}
查看更多
干净又极端
3楼-- · 2020-01-24 19:59

I ran into this exact same thing and the problem was that the wordcount plugin was taking too long to initialize. 30+ seconds. The user would click into the view displaying the ckeditor, then cancel, thereby ajax-loading a new page into the dom. The plugin was complaining because the iframe or whatever contentWindow is pointing to was no longer visible by the time it was ready to add itself to the contentWindow. You can verify this by clicking into your view and then waiting for the Word Count to appear in the bottom right of the editor. If you cancel now, you won't have a problem. If you don't wait for it, you'll get the i.contentWindow is null error. To fix it, just scrap the plugin:

if (CKEDITOR.instances['textarea_name']) 
{
   CKEDITOR.instances['textarea_name'].destroy();
}
CKEDITOR.replace('textarea_name', { removePlugins: "wordcount" } );

If you need a word counter, register for the paste and keyup events on the editor with a function that counts the words.

查看更多
时光不老,我们不散
4楼-- · 2020-01-24 20:00

This is the simplest (and only) solution that worked for me:

if(CKEDITOR.instances[editorName])
   delete CKEDITOR.instances[editorName];
CKEDITOR.replace(editorName);

Deleting this entry in the array prevents this form safety check from destroying your application.

destroy() and remove() did not work for me.

查看更多
forever°为你锁心
5楼-- · 2020-01-24 20:00

CKeditor 4.2.1

There is a lot of answers here but for me I needed something more (bit dirty too so if anyone can improve please do). For me MODALs where my issue.

I was rendering the CKEditor in a modal, using Foundation. Ideally I would have destoryed the editor upon closing, however I didn't want to mess with Foundation.

I called delete, I tried remove and another method but this was what I finally settled with.

I was using textarea's to populate not DIVs.

My Solution

//hard code the DIV removal (due to duplication of CKeditors on page however they didn't work)

    $("#cke_myckeditorname").remove();


     if (CKEDITOR.instances['myckeditorname']) {
                delete CKEDITOR.instances['myckeditorname'];
                CKEDITOR.replace('myckeditorname', GetCKEditorSettings());
            } else {
                CKEDITOR.replace('myckeditorname', GetCKEditorSettings());
            }

this was my method to return my specific formatting, which you might not want.

    function GetCKEditorSettings()
    {
       return {
                    linkShowAdvancedTab: false,
                    linkShowTargetTab: false,
                    removePlugins: 'elementspath,magicline',
                    extraAllowedContent: 'hr blockquote div',
                    fontSize_sizes: 'small/8px;normal/12px;large/16px;larger/24px;huge/36px;',
                    toolbar: [
                        ['FontSize'],
                        ['Bold', 'Italic', 'Underline', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'],
                        ['Smiley']
                    ]
                };
    }
查看更多
劳资没心,怎么记你
6楼-- · 2020-01-24 20:01

This is the fully working code for jquery .load() api and ckeditor, in my case I am loading a page with ckeditor into div with some jquery effects. I hope it will help you.

 $(function() {
            runEffect = function(fileload,lessonid,act) {
            var selectedEffect = 'drop';
            var options = {};
            $( "#effect" ).effect( selectedEffect, options, 200, callback(fileload,lessonid,act) );
        };
        function callback(fileload,lessonid,act) {
            setTimeout(function() {//load the page in effect div
                $( "#effect" ).load(fileload,{lessonid:lessonid,act:act});
                 $("#effect").show( "drop", 
                          {direction: "right"}, 200 );
                $("#effect").ajaxComplete(function(event, XMLHttpRequest, ajaxOptions) {
                    loadCKeditor(); //call the function after loading page
                });
            }, 100 );   
        };

        function loadCKeditor()
        {//you need to destroy  the instance if already exist
            if (CKEDITOR.instances['introduction']) 
            {
                CKEDITOR.instances['introduction'].destroy();
            }
            CKEDITOR.replace('introduction').getSelection().getSelectedText();
        }
    });

===================== button for call the function ================================

<input type="button" name="button" id="button" onclick="runEffect('lesson.php','','add')" >
查看更多
男人必须洒脱
7楼-- · 2020-01-24 20:02

I've had similar issue where we were making several instances of CKeditor for the content loaded via ajax.

CKEDITOR.remove()

Kept the DOM in the memory and didn't remove all the bindings.

CKEDITOR.instance[instance_id].destroy()

Gave the error i.contentWindow error whenever I create new instance with new data from ajax. But this was only until I figured out that I was destroying the instance after clearing the DOM.

Use destroy() while the instance & it's DOM is present on the page, then it works perfectly fine.

查看更多
登录 后发表回答