Die CKEditor-Instanz ist bereits vorhanden

99

Ich verwende jquery-Dialoge, um Formulare zu präsentieren (abgerufen über AJAX). Auf einigen Formularen verwende ich einen CKEditor für die Textbereiche. Der Editor wird beim ersten Laden einwandfrei angezeigt.

Wenn der Benutzer den Dialog abbricht, entferne ich den Inhalt, damit er bei einer späteren Anforderung frisch geladen wird. Das Problem ist, dass der CKEditor nach dem erneuten Laden des Dialogfelds behauptet, der Editor sei bereits vorhanden.

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

Die API enthält eine Methode zum Zerstören vorhandener Editoren, und ich habe Leute gesehen, die behaupteten, dies sei eine Lösung:

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

Dies funktioniert bei mir nicht, da ich stattdessen einen neuen Fehler erhalte:

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

Dieser Fehler scheint eher bei "destroy ()" als bei "replace ()" aufzutreten. Hat jemand dies erlebt und eine andere Lösung gefunden?

Ist es möglich, den vorhandenen Editor neu zu rendern, anstatt ihn zu zerstören und zu ersetzen?

AKTUALISIERT Hier ist eine weitere Frage, die sich mit demselben Problem befasst, aber er hat einen Testfall zum Herunterladen bereitgestellt .

Jackboberg
quelle

Antworten:

101

Damit dies funktioniert, müssen Sie beim Zerstören der Instanz den booleschen Parameter true übergeben :

    var editor = CKEDITOR.instances[name];
    if (editor) { editor.destroy(true); }
    CKEDITOR.replace(name);
Tomas Kirda
quelle
2
Die "wahren" Optionen machen den Unterschied. Erwähnenswert ist auch, dass die unten angegebene Antwort "CKEDITOR.remove (instance)" keine gute Lösung ist, da es sich um eine interne API handelt, die ebenfalls Fehler verursachen kann. Es ist immer besser, instance.destroy (true)
Bala Clark zu verwenden
Danke, das hilft mir wirklich.
unvollständig
6
Machen Sie mit im Chor der Dankeschöns! Ich finde es toll, dass Stack Overflow immer alle meine Probleme mit einer Suche löst.
Tommi Forsström
1
Diese Antwort ist so nützlich, ich bin überrascht, dass sie hier so tief vergraben ist.
Petr Vostrel
2
Es hätte eine Option geben müssen, um die Antworten nach der Anzahl der Stimmen zu sortieren, die sie erhalten haben. Damit die besten Antworten ganz oben stehen.
Shasi Kanth
28
function loadEditor(id)
{
    var instance = CKEDITOR.instances[id];
    if(instance)
    {
        CKEDITOR.remove(instance);
    }
    CKEDITOR.replace(id);
}
Jim
quelle
Das hat mich ein bisschen betrübt, aber Ihre Lösung hat geholfen. Vielen Dank!
Ben Scheirman
Ich hatte ein ähnliches Problem in Firefox, das drei Instanzen des CKEditor auf der Seite hatte. Die erste wurde nicht angezeigt, aber die anderen beiden, bei denen ich den obigen Code hinzugefügt habe und alle Editoren jetzt angezeigt werden
Craig Angus
18
Verwenden Sie CKEDITOR.remove nicht, da nur das Element aus dem Array gelöscht wird, aber das gesamte DOM im Speicher verbleibt. In den Dokumenten wird angegeben, dass es für den internen Gebrauch bestimmt ist: docs.cksource.com/ckeditor_api/symbols/CKEDITOR.html#.remove Sie sollten stattdessen instace.destroy () verwenden, wie madhaviaddanki sagte.
AlfonsoML
2
Ist auf dieselbe Situation gestoßen und wie bereits erwähnt, ist diese Antwort falsch. Die Verwendung von destroy () und die Übergabe des wahren Parameters hat schließlich für mich funktioniert, wie unten angegeben.
Mathachew
19

Ich hatte dieses Problem auch, aber ich habe es viel einfacher gelöst ...

Ich habe die Klasse "ckeditor" in meinem jQuery-Skript als Selektor für die Textbereiche verwendet, die ich für CKEditor verwenden wollte. Das Standard-JS-Skript ckeditor verwendet diese Klasse auch, um zu identifizieren, welche Textbereiche für CKEditor verwendet werden sollen.

Dies bedeutet, dass ein Konflikt zwischen meinem jQuery-Skript und dem Standard-ckeditor-Skript besteht.

Ich habe einfach die Klasse des Textbereichs und mein jQuery-Skript in 'do_ckeditor' geändert (Sie können alles außer "ckeditor" verwenden) und es hat funktioniert.

MintDeparture
quelle
danke, ja, das "automatische" ckeditorizing hat mich auch durcheinander gebracht. siehe auch stackoverflow.com/a/3631391/923817
D.Tate
11

Dies ist die einfachste (und einzige) Lösung, die für mich funktioniert hat:

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

Durch Löschen dieses Eintrags im Array wird verhindert, dass diese Formularsicherheitsprüfung Ihre Anwendung zerstört.

destroy () und remove () hat bei mir nicht funktioniert.

adu
quelle
1
Dies ist die einzige Lösung, die auch bei mir funktioniert hat, danke für die Veröffentlichung!
Michael Robinson
Ich habe destroy () zur Arbeit gebracht. Die Editorinstanz wird jedoch weder vollständig deletenoch destroy()vollständig bereinigt. Dinge wie das Wörterbuch und andere zugehörige Objekte lauern immer noch herum.
Adu
Ich habe instance.destroy (true) ausprobiert, aber es hat bei mir nicht funktioniert. Aber dieser hat für mich funktioniert. Kann mir bitte jemand sagen, gibt es irgendwelche Nebeneffekte davon?
Alex
7

Vielleicht hilft Ihnen das weiter - ich habe mit jquery etwas Ähnliches gemacht, außer dass ich eine unbekannte Anzahl von ckeditor-Objekten lade. Es hat eine Weile gedauert, bis ich darauf gestoßen bin - das ist in der Dokumentation nicht klar.

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

Und hier ist, was ich laufen lasse, um den Inhalt von den Redakteuren zu erhalten:

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

UPDATE : Ich habe meine Antwort geändert, um die richtige Methode zu verwenden - nämlich .destroy (). .remove () soll intern sein und wurde an einer Stelle nicht ordnungsgemäß dokumentiert.

ScottE
quelle
Dies scheint die Fehler beseitigt zu haben, aber beim zweiten Rendern enthält der Textbereich jetzt 'null' und ich kann nicht mehr mit der Symbolleiste oder dem Textbereich interagieren. Wenn ich auf Symbolleistenschaltflächen klicke, erhalte ich folgende Fehler: "TypeError: Ergebnis des Ausdrucks 'this. $. Focus' [undefiniert] ist keine Funktion" -oder- "TypeError: Ergebnis des Ausdrucks 'this.document.getWindow () . $ '[undefiniert] ist kein Objekt ". Wo / wann rufen Sie diese Funktion auf? Ich habe mein Skript mit dem von jquery geladenen Inhalt inline. (ckeditor.js im Kopf des übergeordneten HTML)
Jackboberg
Ich rufe dies auf, nachdem alle Textbereiche zur Seite hinzugefügt und mit Inhalten gefüllt wurden.
ScottE
5

Ich hatte ein ähnliches Problem, bei dem wir mehrere Instanzen von CKeditor für den über Ajax geladenen Inhalt erstellt haben.

CKEDITOR.remove ()

Hielt das DOM im Speicher und entfernte nicht alle Bindungen.

CKEDITOR.instance [instance_id] .destroy ()

Hat den Fehler i.contentWindow angezeigt , wenn ich eine neue Instanz mit neuen Daten von Ajax erstelle. Dies war jedoch nur so lange, bis ich herausfand, dass ich die Instanz nach dem Löschen des DOM zerstörte.

Verwenden Sie destroy (), während die Instanz und das DOM auf der Seite vorhanden sind. Dann funktioniert es einwandfrei.

Tejas
quelle
5

Für Ajax-Anfragen,

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

Durch diesen Ausschnitt werden alle Instanzen aus dem Dokument entfernt. Dann werden neue Instanzen erstellt.

nerkn
quelle
5
var e= CKEDITOR.instances['sample'];
e.destroy();
e= null;
madhaviaddanki
quelle
3

Der i.contentWindow is nullFehler scheint beim Aufrufen von destroy für eine Editorinstanz aufzutreten, die an einen Textbereich gebunden war, der sich nicht mehr im DOM befindet.

CKEDITORY.destroynimmt einen Parameter noUpdate.

Der APIdoc gibt an:

Wenn die Instanz ein DOM-Element ersetzt, gibt dieser Parameter an, ob das Element mit dem Instanzinhalt aktualisiert werden soll oder nicht.

Um den Fehler zu vermeiden, rufen Sie entweder destroy auf, bevor Sie das Textarea-Element aus dem DOM entfernen, oder rufen Sie destory (true) auf, um zu vermeiden, dass versucht wird, das nicht vorhandene DOM-Element zu aktualisieren.

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

(unter Verwendung von Version 3.6.2 mit jQuery-Adapter)

Scott Nelson
quelle
3

Das hat bei mir funktioniert:

for(name in CKEDITOR.instances)
{
  CKEDITOR.instances[name].destroy()
}
mikemike396
quelle
Stellen Sie sicher, dass Ihr "Abbrechen" -Code etwas Ähnliches aufruft! Mein Problem war, dass mein Abbruch nicht zerstörte :)
ROunofF
2
CKEDITOR.instances = new Array();

Ich verwende dies vor meinen Aufrufen, um eine Instanz zu erstellen (eine pro Seite laden). Ich bin mir nicht sicher, wie sich dies auf die Speicherbehandlung auswirkt und was nicht. Dies würde nur funktionieren, wenn Sie alle Instanzen auf einer Seite ersetzen möchten.

Andrew
quelle
1
Ich habe alle Lösungen auf dieser Seite ausprobiert ... für meine Umgebung ist dies die einzige, die funktioniert hat (aber in meinem ie9 nur FF nicht richtig funktioniert hat) ... nicht sicher, warum die anderen es nicht getan haben, aber nach 1 Stunde Dies ist die einzige Lösung, die für mich funktioniert hat. Danke, dass du diesen Andrew gepostet hast.
Ronedog
2

Ich habe meine eigene Lösung basierend auf allen oben genannten Codes vorbereitet.

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

Es funktioniert perfekt für mich.

Manchmal liegt nach einer AJAX-Anforderung eine falsche DOM-Struktur vor. Zum Beispiel:

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

Dies führt ebenfalls zu Problemen und ckEditor funktioniert nicht. Stellen Sie also sicher, dass Sie die richtige DOM-Struktur haben.

Tomasz Maj
quelle
2

Ich hatte das gleiche Problem mit Instanzen, ich habe überall gesucht und schließlich funktioniert diese Implementierung für mich:



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

Sie können jede ckeditor-Instanz entfernen, indem Sie die Methode ckeditor entfernen. Die Instanz ist die ID oder der Name des Textbereichs.

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

In der Tat löst das Entfernen der Klasse ".ckeditor" aus Ihrem Code das Problem. Die meisten von uns folgten dem Integrationsbeispiel für jQuery aus der Dokumentation des ckeditors:

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

und dachte "... vielleicht kann ich einfach loswerden oder den '.jquery_'-Teil".

Ich habe meine Zeit damit verschwendet, die Rückruffunktion zu optimieren (weil {skin: 'office2003'} tatsächlich funktioniert hat), während das Problem von einem anderen Ort kam.

Ich denke, in der Dokumentation sollte erwähnt werden, dass die Verwendung von "ckeditor" als Klassenname nicht empfohlen wird, da es sich um ein reserviertes Schlüsselwort handelt.

Prost.

Ramkam
quelle
1

Ich habe das gelernt

lösche CKEDITOR.instances [editorName];

von sich aus tatsächlich die Instanz entfernt. Alle anderen Methoden, die ich gelesen und gesehen habe, einschließlich der hier bei stackoverflow von seinen Benutzern gefundenen, haben bei mir nicht funktioniert.

In meiner Situation verwende ich einen Ajax-Aufruf, um eine Kopie des Inhalts abzurufen, der um die und 's gewickelt ist. Das Problem liegt zufällig darin, dass ich ein jQuery .live-Ereignis verwende, um einen Link "Dieses Dokument bearbeiten" zu binden und dann die ckeditor-Instanz nach erfolgreichem Laden von Ajax anzuwenden. Dies bedeutet, dass ich, wenn ich auf einen anderen Link klicke, einen Link mit einem anderen .live-Ereignis, die Datei CKEDITOR.instances [editorName] löschen als Teil meiner Aufgabe verwenden muss, das Inhaltsfenster zu löschen (das Formular zu halten) und dann den gehaltenen Inhalt erneut abzurufen in der Datenbank oder einer anderen Ressource.

Nicholas Maietta
quelle
1

Ich hatte das gleiche Problem mit einem jQuery-Dialog.

Warum die Instanz zerstören, wenn Sie nur vorherige Daten entfernen möchten?

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

Ich habe mich dafür entschieden, alle Instanzen umzubenennen, anstatt sie zu zerstören / zu ersetzen - da die von AJAX geladene Instanz manchmal die Instanz im Kern der Seite nicht wirklich ersetzt ... hält mehr im RAM, aber weniger Konflikte auf diese Weise.

    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];
        }
    }
Zeroasterisk
quelle
1

Ich bin in der Situation, in der ich steuern muss, dass Dialoge erzeugt werden. In jedem von ihnen muss ein ckeditor in diese Dialoge eingebettet sein. Und es passiert einfach so, dass die Textbereiche dieselbe ID haben. (Normalerweise ist dies eine sehr schlechte Praxis, aber ich habe 2 jqGrids, eines von zugewiesenen Elementen und eines von nicht zugewiesenen Elementen.) Sie haben eine fast identische Konfiguration. Daher verwende ich gemeinsamen Code, um beide zu konfigurieren.

Wenn ich also einen Dialog lade, um Zeilen hinzuzufügen oder zu bearbeiten, entweder aus jqGrid; Ich muss alle Instanzen von CKEDITOR in allen Textbereichen entfernen.

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

    }
});

Dadurch werden alle Textbereiche durchlaufen. Wenn eine CKEDITOR-Instanz vorhanden ist, zerstören Sie diese.

Alternativ, wenn Sie reine jQuery verwenden:

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

    }
});
DragonZero
quelle
1

entfernen class="ckeditor", es könnte ckeditor Initialisierung ausgelöst haben

vkGunasekaran
quelle
0

Ich hatte das gleiche Problem, bei dem ich eine Nullreferenzausnahme erhielt und das Wort "null" im Editor angezeigt wurde. Ich habe eine Handvoll Lösungen ausprobiert, darunter das vergebliche Upgrade des Editors auf 3.4.1.

Am Ende musste ich die Quelle bearbeiten. Ungefähr in den Zeilen 416 bis 426 in _source \ plugins \ wysiwygarea \ plugin.js befindet sich ein Snippet wie das folgende:

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

Zumindest in FF wird der Iframe nicht vollständig instanziiert, wenn er benötigt wird. Ich habe den Rest der Funktion nach dieser Zeile mit einer setTimeout-Funktion umgeben:

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

Der Text wird jetzt in den modalen Dialogen konsistent gerendert.

Aaron Stemen
quelle
0

Um das dynamische (Ajax) Laden von Formularen (ohne Seitenaktualisierungen dazwischen) zu unterstützen, die Textbereiche mit derselben (dasselbe Formular wird erneut aufgerufen) oder unterschiedlichen IDs (zuvor entladenes Formular) enthalten, und diese in CKEditor-Elemente zu konvertieren, habe ich Folgendes ausgeführt (mithilfe von JQuery) Adapter):

Nachdem die Seite jeden Ajax-Aufruf beendet hat, der einen zu konvertierenden Textbereich liefert, rufe ich die folgende Funktion auf:

setupCKeditor()

Dies sieht folgendermaßen aus (es wird davon ausgegangen, dass Ihre Textbereiche in RTEs konvertiert werden, haben 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);

            });

    }


}

Ich sollte erwähnen, dass die Zeile:

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

könnte (und sollte) einfach sein:

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

Ich stellte jedoch fest, dass der Editor nach dem Laden häufig für eine Sekunde den richtigen Inhalt anzeigt und der Editor den gewünschten Inhalt leert. Diese Zeile mit dem Rückrufcode erzwingt also, dass der CKEditor-Inhalt mit dem ursprünglichen Textbereichsinhalt übereinstimmt. Verursacht bei Verwendung ein Flimmern. Wenn Sie es vermeiden können, tun Sie dies.

Belaubt
quelle
0

Ich hatte genau das gleiche Problem wie Jackboberg. Ich habe das dynamische Laden von Formularen in jquery-Dialoge verwendet und dann verschiedene Widgets (Datepicker, ckeditors usw.) angehängt. Und ich habe alle oben genannten Lösungen ausprobiert, keine davon hat für mich funktioniert.

Aus irgendeinem Grund hat ckeditor nur beim ersten Laden des Formulars angehängt, beim zweiten Mal habe ich genau die gleiche Fehlermeldung erhalten, die jackboberg erhalten hat.

Ich habe meinen Code analysiert und festgestellt, dass ckeditor seine Bindungen nicht ordnungsgemäß anfügt, wenn Sie ckeditor in "mid-air" anhängen, während der Formularinhalt noch nicht in den Dialog gestellt wird. Das heißt, da ckeditor in "mid-air" angehängt ist, wird beim zweiten Anschließen in "mid-air" ... poof ... ein Fehler ausgegeben, da die erste Instanz nicht ordnungsgemäß aus DOM entfernt wurde.

Dies war mein Code, der den Fehler verursachte:

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

Dies ist das Update, das funktioniert hat:

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

Ich bin genau auf dasselbe gestoßen und das Problem war, dass die Initialisierung des Wordcount-Plugins zu lange dauerte. 30+ Sekunden. Der Benutzer klickt in die Ansicht, in der der ckeditor angezeigt wird, und bricht dann ab, wodurch eine neue Seite in den Dom geladen wird. Das Plugin hat sich beschwert, weil der Iframe oder was auch immer contentWindow zeigt, nicht mehr sichtbar war, als es bereit war, sich selbst zum contentWindow hinzuzufügen. Sie können dies überprüfen, indem Sie in Ihre Ansicht klicken und dann darauf warten, dass die Wortanzahl unten rechts im Editor angezeigt wird. Wenn Sie jetzt kündigen, haben Sie kein Problem. Wenn Sie nicht darauf warten, wird der Fehler i.contentWindow null angezeigt. Um das Problem zu beheben, verschrotten Sie einfach das Plugin:

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

Wenn Sie einen Wortzähler benötigen, registrieren Sie sich für die Einfüge- und Eingabeereignisse im Editor mit einer Funktion, die die Wörter zählt.

Sean Roy
quelle
0

Für diejenigen, die den jquery "Adapter" verwenden und Probleme haben (wie ich), ist es eine super hackige und dennoch funktionierende Lösung, Folgendes zu tun:

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

});

Der entscheidende Punkt ist dieser Teil:

                'open': function() {
                    $ew.find('a.cke_button_source').click();

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

Dies behebt das Problem, dass der Editortext beim nächsten Öffnen des Dialogfelds nicht sichtbar ist. Mir ist klar, dass dies sehr hackisch ist, aber wenn man bedenkt, dass die meisten davon für Admin-Tools verwendet werden, denke ich nicht, dass dies ein so großes Problem ist, wie es normalerweise wäre. Und das funktioniert, also wird es hoffentlich jemandem etwas ersparen Zeit ;)

Eva
quelle
0

Dies ist der voll funktionsfähige Code für jquery .load () api und ckeditor. In meinem Fall lade ich eine Seite mit ckeditor in div mit einigen jquery-Effekten. Ich hoffe es hilft dir.

 $(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')" >
Khandad Niazi
quelle
0

Es ist ziemlich einfach. In meinem Fall habe ich die folgende jquery-Methode ausgeführt, die ckeditor-Instanzen während des Ladens einer Seite zerstört. Dies hat den Trick getan und das Problem behoben -

JQuery-Methode -

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

       });

Das ist es. Ich hoffe es hilft dir.

Prost, Sirish.

Sirish
quelle
0

Diese Funktion funktioniert bei mir in CKEditor Version 4.4.5, es gibt keine Speicherlecks

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

// rufe diese Funktion wie folgt auf

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

CKEditor_Render(id);
Shujaat Kagathra
quelle
0

CKeditor 4.2.1

Hier gibt es viele Antworten, aber für mich brauchte ich etwas mehr (auch etwas schmutzig, wenn sich jemand verbessern kann, bitte tun). Für mich waren MODALE mein Problem.

Ich habe den CKEditor mithilfe von Foundation modal gerendert. Im Idealfall hätte ich den Editor beim Schließen zerstört, aber ich wollte mich nicht mit Foundation anlegen.

Ich rief delete an, versuchte es mit remove und einer anderen Methode, aber damit war ich schließlich einverstanden.

Ich habe Textbereiche verwendet, um keine DIVs zu füllen.

Meine Lösung

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

Dies war meine Methode, um meine spezifische Formatierung zurückzugeben, die Sie möglicherweise nicht möchten.

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

Versuche dies:

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