multiple javascript ckeditor
caso de prueba descargable

javascript - multiple - La instancia de CKEditor ya existe



ckeditor install (30)

Estoy usando los cuadros de diálogo jquery para presentar formularios (obtenidos a través de AJAX). En algunos formularios, estoy usando un CKEditor para las áreas de texto. El editor muestra bien en la primera carga.

Cuando el usuario cancela el diálogo, elimino los contenidos para que se carguen frescos en una solicitud posterior. El problema es que, una vez que se vuelve a cargar el diálogo, CKEditor afirma que el editor ya existe.

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

La API incluye un método para destruir los editores existentes, y he visto a personas que afirman que esta es una solución:

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

Esto no funciona para mí, ya que recibo un nuevo error en su lugar:

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

Este error parece ocurrir en "destroy ()" en lugar de "replace ()". ¿Alguien ha experimentado esto y ha encontrado una solución diferente?

¿Es posible volver a procesar el editor existente, en lugar de destruirlo y reemplazarlo?

ACTUALIZADO Aquí hay otra pregunta que trata el mismo problema, pero ha proporcionado un caso de prueba descargable .


CKeditor 4.2.1

Aquí hay muchas respuestas, pero para mí necesitaba algo más (un poco sucio, así que si alguien puede mejorar, por favor). Para mí MODALES donde mi problema.

Estaba renderizando el CKEditor en un modal, usando Foundation. Idealmente, habría descartado al editor al cierre, sin embargo no quería meterme con Foundation.

Llamé a eliminar, intenté eliminar y otro método, pero esto fue con lo que finalmente me conformé.

Estaba usando textarea''s para poblar no DIVs.

Mi solución

//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()); }

este fue mi método para devolver mi formato específico, que es posible que no desee.

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''] ] }; }


De hecho, eliminar la clase ".ckeditor" de su código resuelve el problema. La mayoría de nosotros seguimos el ejemplo de integración jQuery de la documentación del ckeditor:

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

y pensé: "... tal vez solo pueda deshacerme o la ''.jquery_'' parte".

He estado perdiendo el tiempo ajustando la función de devolución de llamada (porque {skin: ''office2003''} realmente funcionó), mientras que el problema venía de otro lado.

Creo que la documentación debería mencionar que no se recomienda el uso de "ckeditor" como nombre de clase, porque es una palabra clave reservada.

Aclamaciones.


Elegí cambiar el nombre de todas las instancias en lugar de destroy / replace, ya que a veces la instancia cargada de AJAX no reemplaza realmente la que está en el núcleo de la página ... mantiene más memoria RAM, pero menos conflictos de esta manera.

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]; } }


Es bastante simple. En mi caso, ejecuté el siguiente método jquery que destruirá instancias de ckeditor durante una carga de página. Esto hizo el truco y resolvió el problema -

Método JQuery -

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 });

Eso es. Espero que te ayude.

Saludos, Sirish.


Esta es la solución más simple (y única) que funcionó para mí:

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

Eliminar esta entrada en la matriz evita que esta verificación de seguridad del formulario destruya su aplicación.

destroy () y remove () no funcionó para mí.


Esta función funciona para mí en CKEditor versión 4.4.5, no tiene ninguna pérdida de memoria

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

// llame a esta función de la siguiente manera

var id = ''ckeditor''; // Id of your textarea CKEditor_Render(id);


Este es el código completamente funcional para jquery .load () api y ckeditor, en mi caso estoy cargando una página con ckeditor en div con algunos efectos jquery. Espero que te ayude.

$(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'')" >


Esto es lo que funcionó para mí:

for(name in CKEDITOR.instances) { CKEDITOR.instances[name].destroy() }


Estoy en la situación en la que tengo que controlar los diálogos de generación, cada uno de ellos debe tener un ckeditor incrustado dentro de estos cuadros de diálogo. Y sucede que las áreas de texto comparten la misma identificación. (Normalmente esta es una práctica muy mala, pero tengo 2 jqGrids, uno de los elementos asignados y otro de los elementos no asignados). Comparten una configuración casi idéntica. Por lo tanto, estoy usando un código común para configurar ambos.

Entonces, cuando cargo un diálogo, para agregar filas, o para editarlas, desde cualquiera de los jqGrid; Debo eliminar todas las instancias de CKEDITOR en todas las áreas de texto.

$(''textarea'').each(function() { try { if(CKEDITOR.instances[$(this)[0].id] != null) { CKEDITOR.instances[$(this)[0].id].destroy(); } } catch(e) { } });

Esto recorrerá todas las áreas de texto, y si hay una instancia de CKEDITOR, entonces destrúyala.

Alternativamente si usa jQuery puro:

$(''textarea'').each(function() { try { $(this).ckeditorGet().destroy(); } catch(e) { } });


He preparado mi propia solución basada en todos los códigos anteriores.

$("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); } });

Funciona perfectamente para mí.

Algunas veces, después de la solicitud de AJAX, hay una estructura DOM incorrecta. Para instace:

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

Esto causará problemas también, y ckEditor no funcionará. Así que asegúrese de tener una estructura DOM correcta.


La i.contentWindow is null error i.contentWindow is null parece ocurrir al llamar a destroy en una instancia del editor que estaba vinculada a un área de texto ya no en el DOM.

CKEDITORY.destroy toma un parámetro noUpdate .

El APIdoc dice:

Si la instancia reemplaza un elemento DOM, este parámetro indica si actualizará o no el elemento con los contenidos de la instancia.

Entonces, para evitar el error, llame a destroy antes de eliminar el elemento textarea del DOM, o llame a destory (verdadero) para evitar tratar de actualizar el elemento DOM no existente.

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

(usando la versión 3.6.2 con el adaptador jQuery)


Me encontré con exactamente lo mismo y el problema fue que el complemento de wordcount tardaba demasiado en inicializarse. Más de 30 segundos El usuario haría clic en la vista que mostraba el ckeditor y luego cancelaría, con lo que ajax cargaría una nueva página en el dom. El complemento se quejaba porque el iframe o el contenido al que apuntaba la ventana ya no estaba visible cuando estaba listo para agregarse a contentWindow. Puede verificar esto haciendo clic en su vista y luego esperando que aparezca Word Count en la parte inferior derecha del editor. Si cancelas ahora, no tendrás un problema. Si no lo espera, obtendrá i.contentWindow es un error nulo. Para solucionarlo, simplemente elimine el complemento:

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

Si necesita un contador de palabras, regístrese para los eventos de pegar y escribir en el editor con una función que cuente las palabras.


Para admitir la carga dinámica (Ajax) de formularios (sin actualizaciones de página entre) que contienen áreas de texto con la misma (se llama de nuevo la misma forma) o ID diferentes (formulario descargado previamente) y convertirlos a elementos de CKEditor, hice lo siguiente (usando JQuery adaptador):

Después de que la página ha terminado cada llamada de Ajax que entrega un área de texto para convertir, realizo una llamada a la siguiente función:

setupCKeditor()

Esto se ve así (supone que tus áreas de texto se convertirán a RTE con 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); }); } }

Debo mencionar que la línea:

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

podría (y debería) ser simplemente:

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

sin embargo, encontré que el editor a menudo mostraba el contenido correcto por un segundo después de cargarlo y vaciaba el editor del contenido deseado. De modo que esa línea con el código de devolución de llamada obliga al contenido de CKEditor a ser el mismo que el contenido de texto de origen. Causa un parpadeo cuando se usa. Si puede evitar usarlo, hágalo ...


Para aquellos que usan el "adaptador" jquery y que tienen problemas (como yo), una solución muy hackosa pero funcional es hacer algo como esto:

// content editor plugin (function($){ $.fn.contentEditor = function( params ) { var xParams = $.extend({}, $.fn.contentEditor.defaultParams, params); return this.each( function() { var $editor = $(this); var $params = $.extend({}, xParams, $editor.data()); // if identifier is set, detect type based on identifier in $editor if( $params.identifier.type ) { $params.type = $editor.find($params.identifier.type).val(); } $editor.data(''type'', $params.type); // edit functionality editButton = $(''<button>Edit Content</button>'').on(''click'',function(){ // content container var $cc = $(''#'' + $editor.data(''type'')); // editor window var $ew = $(''<form class="editorWindow" />''); $ew.appendTo(''body''); // editor content $ec = $(''<textarea name="editorContent" />'').val($cc.html()); $ec.appendTo($ew); $ec.ckeditor(); //$ec.ckeditorGet().setMode(''source''); $ew.dialog({ "autoOpen": true, "modal": true, "draggable": false, "resizable": false, "width": 850, "height": ''auto'', "title": "Content Editor", "buttons": { ''Save'': function() { $cc.html( $ec.val() ); $ec.ckeditorGet().destroy(); $ew.remove(); }, ''Cancel / Close'': function() { $ec.ckeditorGet().destroy(); $ew.remove(); } }, ''close'': function() { $ec.ckeditorGet().destroy(); }, ''open'': function() { $ew.find(''a.cke_button_source'').click(); setTimeout(function(){ $ew.find(''a.cke_button_source.cke_on'').click(); }, 500); } }); return false; }); editButton.appendTo( $editor ); }); } // set default option values $.fn.contentEditor.defaultParams = { ''identifier'': { ''type'': ''input[name="type"]'' } }; })(jQuery); $(function(){ $(''form.contentEditor'').contentEditor(); });

El punto clave es esta parte:

''open'': function() { $ew.find(''a.cke_button_source'').click(); setTimeout(function(){ $ew.find(''a.cke_button_source.cke_on'').click(); }, 500); }

Esto soluciona el problema con el texto del editor que no está visible la próxima vez que abre el cuadro de diálogo. Me doy cuenta de que esto es muy hackoso, pero considerando que la mayoría de estos se usarán para herramientas de administración, no creo que sea una gran preocupación como lo sería normalmente ... y esto funciona, así que con suerte salvará a alguien hora ;)


Para que esto funcione, debe pasar el parámetro booleano true cuando se destruye la instancia:

var editor = CKEDITOR.instances[name]; if (editor) { editor.destroy(true); } CKEDITOR.replace(name);


Para solicitudes ajax,

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

este recorte elimina todas las instancias del documento. Luego crea nuevas instancias.


Prueba esto:

for (name in CKEDITOR.instances) { CKEDITOR.instances[name].destroy(true); }


Puede eliminar cualquier instancia de ckeditor eliminando el método de ckeditor. La instancia será id o nombre del área de texto.

if (CKEDITOR.instances[instance_name]) { CKEDITOR.remove(CKEDITOR.instances[instance_name]); }


Tal vez esto te ayude: he hecho algo similar usando jquery, excepto que estoy cargando un número desconocido de objetos ckeditor. Me tomó un tiempo tropezar con esto, no está claro en la documentación.

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); }); } }

Y aquí está lo que corro para obtener el contenido de los editores:

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

ACTUALIZACIÓN : He cambiado mi respuesta para usar el método correcto, que es .destroy (). .remove () está destinado a ser interno, y fue incorrectamente documentado en un punto.


También tuve este problema, pero lo resolví de una manera mucho más simple ...

Estaba usando la clase "ckeditor" en mi script de jQuery como el selector para el cual utilicé las áreas de texto que quería para CKEditor. El script JS de ckeditor predeterminado también usa esta clase para identificar qué áreas de texto usar para CKEditor.

Esto significa que hay un conflicto entre mi script jQuery y el script ckeditor predeterminado.

Simplemente cambié la clase de textarea y mi script jQuery a ''do_ckeditor'' (puedes usar cualquier cosa excepto "ckeditor") y funcionó.


Tenía exactamente el mismo problema que Jackboberg. Estaba usando la carga dinámica de formularios en diálogos de jquery y luego adjunto varios widgets (datapickers, ckeditors, etc ...). Y probé todas las soluciones mencionadas anteriormente, ninguna de ellas funcionó para mí.

Por alguna razón, ckeditor solo adjuntó la primera vez que cargué el formulario, la segunda vez que recibí exactamente el mismo mensaje de error que jackboberg.

He analizado mi código y descubrí que si adjuntas ckeditor en "medio del aire", es decir, mientras el contenido del formulario aún no se coloca en el cuadro de diálogo, ckeditor no adjuntará correctamente sus enlaces. Eso es porque ckeditor está conectado en "medio del aire", la segunda vez que lo colocas en "medio del aire" ... poof ... se produce un error ya que la primera instancia no se eliminó correctamente de DOM.

Este fue mi código que produjo el 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();

Esta es la solución que funcionó:

var $content = $(r.content).dialog(); // first create dialog $(''.rte-field'',$content).ckeditor(function(){}); // then attach ckeditor widget


Tuve el mismo problema con un diálogo de jQuery.

¿Por qué destruir la instancia si solo desea eliminar datos anteriores?

function clearEditor(id) { var instance = CKEDITOR.instances[id]; if(instance) { instance.setData( '''' ); } }


Tuve el mismo problema cuando recibí una excepción de referencia nula y la palabra "nulo" se mostraría en el editor. Probé algunas soluciones, incluida la actualización del editor a 3.4.1 en vano.

Terminé teniendo que editar la fuente. En la línea 416 a 426 en _source / plugins / wysiwygarea / plugin.js, hay un fragmento como este:

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

En FF al menos, el iframe no está completamente instanciado para el momento en que se necesita. Rodeé el resto de la función después de esa línea con una función setTimeout:

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 ...

El texto se representa consistentemente ahora en los cuadros de diálogo modales.


Tuve un problema similar en el que estábamos realizando varias instancias de CKeditor para el contenido cargado a través de ajax.

CKEDITOR.remove ()

Mantuvo el DOM en la memoria y no eliminó todas las vinculaciones.

CKEDITOR.instance [instance_id] .destroy ()

Dio el error i.contentWindow error cada vez que creo una nueva instancia con nuevos datos de ajax. Pero esto fue solo hasta que descubrí que estaba destruyendo la instancia después de borrar el DOM.

Usa destroy () mientras la instancia y su DOM están presentes en la página, entonces funciona perfectamente bien.


aprendí eso

eliminar CKEDITOR.instances [editorName];

por sí mismo, en realidad eliminó la instancia. TODOS los demás métodos que he leído y visto, incluido lo que se encontró aquí en de sus usuarios, no funcionó para mí.

En mi situación, estoy usando una llamada ajax para obtener una copia del contenido que rodea el y ''s. El problema se debe a que estoy usando un evento jQuery .live para enlazar un enlace "Editar este documento" y luego aplicar la instancia de ckeditor después del éxito de la carga de AJAX. Esto significa, que cuando hago clic en otro enlace un enlace con otro evento .live, debo usar la eliminación de CKEDITOR.instances [editorName] como parte de mi tarea de borrar la ventana de contenido (manteniendo el formulario), luego volver a recuperar contenido retenido en la base de datos u otro recurso.


remove class="ckeditor" , podría haber activado la inicialización de ckeditor


tuve el mismo problema con las instancias, estaba buscando en todas partes y finalmente esta implementación me funciona:

//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 });


CKEDITOR.instances = new Array();

Estoy usando esto antes de mis llamadas para crear una instancia (una por carga de página). No estoy seguro de cómo esto afecta el manejo de la memoria y lo que no. Esto solo funcionaría si quisiera reemplazar todas las instancias en una página.


function loadEditor(id) { var instance = CKEDITOR.instances[id]; if(instance) { CKEDITOR.remove(instance); } CKEDITOR.replace(id); }


var e= CKEDITOR.instances[''sample'']; e.destroy(); e= null;