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条回答
爷的心禁止访问
2楼-- · 2020-01-24 19:55

The i.contentWindow is null error seems to occur when calling destroy on an editor instance that was tied to a textarea no longer in the DOM.

CKEDITORY.destroy takes a parameter noUpdate.

The APIdoc states:

If the instance is replacing a DOM element, this parameter indicates whether or not to update the element with the instance contents.

So, to avoid the error, either call destroy before removing the textarea element from the DOM, or call destory(true) to avoid trying to update the non-existent DOM element.

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

(using version 3.6.2 with jQuery adapter)

查看更多
家丑人穷心不美
3楼-- · 2020-01-24 19:55

Indeed, removing the ".ckeditor" class from your code solves the issue. Most of us followed the jQuery integration example from the ckeditor's documentation:

$('.jquery_ckeditor')
.ckeditor( function() { /* callback code */ }, { skin : 'office2003' } );

and thought "... maybe I can just get rid or the '.jquery_' part".

I've been wasting my time tweaking the callback function (because the {skin:'office2003'} actually worked), while the problem was coming from elsewhere.

I think the documentation should mention that the use of "ckeditor" as a class name is not recommended, because it is a reserved keyword.

Cheers.

查看更多
淡お忘
4楼-- · 2020-01-24 19:56

For ajax requests,

 for(k in CKEDITOR.instances){
    var instance = CKEDITOR.instances[k];
    instance.destroy()
 }
  CKEDITOR.replaceAll();

this snipped removes all instances from document. Then creates new instances.

查看更多
beautiful°
5楼-- · 2020-01-24 19:57

I chose to rename all instances instead of destroy/replace - since sometimes the AJAX loaded instance doesn't really replace the one on the core of the page... keeps more in RAM, but less conflict this way.

    if (CKEDITOR && CKEDITOR.instances) {
        for (var oldName in CKEDITOR.instances) {
            var newName = "ajax"+oldName;
            CKEDITOR.instances[newName] = CKEDITOR.instances[oldName];
            CKEDITOR.instances[newName].name = newName;
            delete CKEDITOR.instances[oldName];
        }
    }
查看更多
够拽才男人
6楼-- · 2020-01-24 19:57

I had the same problem where I was receiving a null reference exception and the word "null" would be displayed in the editor. I tried a handful of solutions, including upgrading the editor to 3.4.1 to no avail.

I ended up having to edit the source. At about line 416 to 426 in _source\plugins\wysiwygarea\plugin.js, there's a snippet like this:

iframe = CKEDITOR.dom.element.createFromHtml( '&lt;iframe' + ... + '></iframe>' );

In FF at least, the iframe isn't completely instantiated by the time it's needed. I surrounded the rest of the function after that line with a setTimeout function:

iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' + ... + '></iframe>' );
setTimeout(function()
{ 
    // Running inside of Firefox chrome the load event doesn't bubble like in a normal page (#5689)
    ...
}, 1000);

};

// The script that launches the bootstrap logic on 'domReady', so the document
...

The text renders consistently now in the modal dialogs.

查看更多
老娘就宠你
7楼-- · 2020-01-24 19:58

I had exactly the same problem like jackboberg. I was using dynamic form loading into jquery dialogs then attaching various widgets (datepickers, ckeditors etc...). And I tried all solutions noted above, none of them worked for me.

For some reason ckeditor only attached the first time I loaded form, the second time I got exactly the same error message jackboberg did.

I've analyzed my code and discovered that if you attach ckeditor in "mid-air" that is while form content is still not placed into dialog, ckeditor won't properly attach its bindings. That is since ckeditor is attached in "mid-air", second time you attach it in "mid-air"... poof ... an error is thrown since the first instance was not properly removed from DOM.

This was my code that ptoduced the error:

var $content = $(r.content); // jQuery can create DOM nodes from html text gotten from <xhr response> - so called "mid-air" DOM creation
$('.rte-field',$content).ckeditor(function(){});
$content.dialog();

This is the fix that worked:

var $content = $(r.content).dialog(); // first create dialog
$('.rte-field',$content).ckeditor(function(){}); // then attach ckeditor widget
查看更多
登录 后发表回答