มีอินสแตนซ์ CKEditor อยู่แล้ว


99

ฉันใช้กล่องโต้ตอบ jquery เพื่อนำเสนอแบบฟอร์ม (ดึงข้อมูลผ่าน AJAX) ในบางรูปแบบฉันใช้ CKEditor สำหรับ textareas ตัวแก้ไขแสดงผลได้ดีในการโหลดครั้งแรก

เมื่อผู้ใช้ยกเลิกกล่องโต้ตอบฉันกำลังลบเนื้อหาเพื่อให้มีการโหลดใหม่ตามคำขอในภายหลัง ปัญหาคือเมื่อกล่องโต้ตอบถูกโหลดซ้ำ CKEditor อ้างว่ามีตัวแก้ไขอยู่แล้ว

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

API มีวิธีการทำลายบรรณาธิการที่มีอยู่และฉันเคยเห็นคนที่อ้างว่านี่เป็นวิธีแก้ปัญหา:

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

สิ่งนี้ไม่ได้ผลสำหรับฉันเนื่องจากฉันได้รับข้อผิดพลาดใหม่แทน:

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

ข้อผิดพลาดนี้ดูเหมือนจะเกิดขึ้นบน "destroy ()" แทนที่จะเป็น "replace ()" มีใครประสบปัญหานี้และพบวิธีแก้ปัญหาอื่น ๆ หรือไม่?

เป็นไปได้ไหมที่จะ 're-render' โปรแกรมแก้ไขที่มีอยู่แทนที่จะทำลายและแทนที่

อัปเดต นี่คือคำถามอื่นที่เกี่ยวข้องกับปัญหาเดียวกัน แต่เขาได้จัดเตรียมกรณีทดสอบที่ดาวน์โหลดได้

คำตอบ:


101

เพื่อให้ได้ผลคุณต้องส่งผ่านพารามิเตอร์บูลีนจริงเมื่อทำลายอินสแตนซ์:

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

2
ตัวเลือก "จริง" สร้างความแตกต่าง นอกจากนี้ยังควรค่าแก่การกล่าวถึงว่าคำตอบ "CKEDITOR.remove (อินสแตนซ์)" ที่ระบุด้านล่างไม่ใช่วิธีแก้ปัญหาที่ดีเนื่องจากเป็น API ภายในที่สามารถสร้างข้อผิดพลาดได้เช่นกันจึงควรใช้ instance.destroy (จริง) ดีกว่าเสมอ
Bala Clark

ขอบคุณจริงๆนี้ช่วยฉันออก
ไม่สมบูรณ์

6
เข้าร่วมในคณะนักร้องขอบคุณ! ฉันชอบวิธีที่ Stack Overflow เพียงแค่แก้ปัญหาทั้งหมดของฉันด้วยการค้นหาเพียงครั้งเดียว
Tommi Forsström

1
คำตอบนี้มีประโยชน์มากฉันแปลกใจที่มันฝังลึกลงไปที่นี่
Petr Vostrel

2
ควรมีตัวเลือกในการจัดเรียงคำตอบตามจำนวนโหวตที่ได้รับ .. ดังนั้นคำตอบที่ดีที่สุดจึงอยู่อันดับต้น ๆ
shasi kanth

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

สิ่งนี้ทำให้ฉันเสียใจเล็กน้อย แต่วิธีแก้ปัญหาของคุณช่วยได้ ขอบคุณ!
Ben Scheirman

ฉันมีปัญหาที่คล้ายกันใน firefox ซึ่งมี CKEditor สามอินสแตนซ์บนเพจอันแรกไม่แสดง แต่อีกสองอันที่ฉันเพิ่มโค้ดด้านบนและตอนนี้ตัวแก้ไขทั้งหมดปรากฏขึ้น
Craig Angus

18
อย่าใช้ CKEDITOR.remove เพราะจะล้างองค์ประกอบออกจากอาร์เรย์เท่านั้น แต่จะทิ้ง DOM ทั้งหมดไว้ในหน่วยความจำ มีระบุไว้ในเอกสารว่ามีไว้สำหรับใช้งานภายใน: docs.cksource.com/ckeditor_api/symbols/CKEDITOR.html#.removeคุณควรใช้ instace.destroy () แทนตามที่ madhaviaddanki กล่าว
AlfonsoML

2
วิ่งข้ามสถานการณ์เดียวกันและตามที่ระบุไว้คำตอบนี้ไม่ถูกต้อง การใช้ destroy () และส่งผ่านพารามิเตอร์ true คือสิ่งที่ใช้ได้ผลสำหรับฉันในที่สุดดังที่ระบุไว้ด้านล่าง
Mathachew

19

ฉันมีปัญหานี้เหมือนกัน แต่ฉันแก้ไขด้วยวิธีที่ง่ายกว่านั้นมาก ...

ฉันใช้คลาส "ckeditor" ในสคริปต์ jQuery เป็นตัวเลือกพื้นที่ข้อความที่ฉันต้องการใช้สำหรับ CKEditor สคริปต์ ckeditor JS เริ่มต้นยังใช้คลาสนี้เพื่อระบุพื้นที่ข้อความที่จะใช้สำหรับ CKEditor

ซึ่งหมายความว่ามีข้อขัดแย้งระหว่างสคริปต์ jQuery ของฉันและสคริปต์ ckeditor เริ่มต้น

ฉันเพิ่งเปลี่ยนคลาสของ textarea และสคริปต์ jQuery ของฉันเป็น 'do_ckeditor' (คุณสามารถใช้อะไรก็ได้ยกเว้น "ckeditor") และมันก็ใช้ได้


ขอบคุณใช่ ckeditorizing "อัตโนมัติ" ก็ยุ่งกับฉันเช่นกัน ดูstackoverflow.com/a/3631391/923817
D.Tate

11

นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด (และเท่านั้น) ที่เหมาะกับฉัน:

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

การลบรายการนี้ในอาร์เรย์จะป้องกันไม่ให้การตรวจสอบความปลอดภัยของฟอร์มนี้ทำลายแอปพลิเคชันของคุณ

ทำลาย () และลบ () ไม่ได้ผลสำหรับฉัน


1
นี่เป็นทางออกเดียวที่ใช้ได้กับฉันด้วยขอบคุณที่โพสต์!
Michael Robinson

ฉันถูกทำลาย () ให้ทำงาน แต่ไม่deleteหรือdestroy()ทำความสะอาดอย่างเต็มที่เช่นการแก้ไข สิ่งต่างๆเช่นพจนานุกรมและวัตถุอื่น ๆ ที่เกี่ยวข้องจะยังคงแฝงตัวอยู่
Adu

ฉันลองใช้ instance.destroy (จริง) แต่มันไม่ได้ผลสำหรับฉัน แต่อันนี้ใช้ได้ผลกับฉัน ใครช่วยบอกหน่อยได้ไหมว่ามีผลกระทบด้านนี้หรือไม่?
Manjeet

7

บางทีนี่อาจช่วยคุณได้ - ฉันได้ทำบางสิ่งที่คล้ายกันโดยใช้ jquery ยกเว้นฉันกำลังโหลดวัตถุ ckeditor ที่ไม่ทราบจำนวน ฉันใช้เวลาสักพักกว่าจะสะดุดกับเรื่องนี้ - เอกสารประกอบยังไม่ชัดเจน

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

และนี่คือสิ่งที่ฉันเรียกใช้เพื่อรับเนื้อหาจากบรรณาธิการ:

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

UPDATE : ฉันเปลี่ยนคำตอบให้ใช้วิธีการที่ถูกต้อง - ซึ่งก็คือ .destroy () .remove () หมายถึงภายในและมีการจัดทำเอกสารอย่างไม่ถูกต้อง ณ จุดหนึ่ง


ดูเหมือนว่าจะลบข้อผิดพลาดออกไปแล้ว แต่ในการแสดงผลครั้งที่สอง textarea ตอนนี้มี 'null' และฉันไม่สามารถโต้ตอบกับแถบเครื่องมือหรือ textarea ได้อีกต่อไป ถ้าฉันคลิกที่ปุ่มแถบเครื่องมือฉันได้รับข้อผิดพลาดเช่น: "TypeError: Result of expression 'this. $. focus' [undefined] ไม่ใช่ฟังก์ชัน" -or- "TypeError: Result of expression 'this.document.getWindow () . $ '[undefined] ไม่ใช่วัตถุ " คุณเรียกใช้ฟังก์ชันนั้นที่ไหน / เมื่อใด ฉันมีสคริปต์ของฉันอยู่ในแนวเดียวกับเนื้อหาที่โหลด jquery (ckeditor.js ในส่วนหัวของ html หลัก)
jackboberg

ฉันเรียกสิ่งนี้ว่าหลังจากเพิ่มพื้นที่ข้อความทั้งหมดลงในเพจแล้วและเต็มไปด้วยเนื้อหา
ScottE

5

ฉันมีปัญหาคล้าย ๆ กันที่เราสร้าง CKeditor หลายอินสแตนซ์สำหรับเนื้อหาที่โหลดผ่าน ajax

CKEDITOR.remove ()

เก็บ DOM ไว้ในหน่วยความจำและไม่ได้ลบการผูกทั้งหมด

CKEDITOR.instance [instance_id] .destroy ()

ให้ข้อผิดพลาดi.contentWindow error เมื่อใดก็ตามที่ฉันสร้างอินสแตนซ์ใหม่ด้วยข้อมูลใหม่จาก ajax แต่นี่เป็นเพียงจนกระทั่งฉันรู้ว่าฉันกำลังทำลายอินสแตนซ์หลังจากล้าง DOM

ใช้destroy ()ในขณะที่อินสแตนซ์ & เป็น DOM ปรากฏอยู่บนหน้าจากนั้นก็ทำงานได้ดีอย่างสมบูรณ์


5

สำหรับคำขอของ ajax

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

snipped นี้จะลบอินสแตนซ์ทั้งหมดออกจากเอกสาร จากนั้นสร้างอินสแตนซ์ใหม่



3

i.contentWindow is nullข้อผิดพลาดดูเหมือนว่าจะเกิดขึ้นเมื่อมีการโทรทำลายบนอินสแตนซ์แก้ไขที่ถูกผูกติดอยู่กับ textarea ไม่มีอีกต่อไปได้ใน DOM

CKEDITORY.destroy รับพารามิเตอร์ noUpdateใช้เวลาพารามิเตอร์

สถานะ APIdoc:

หากอินสแตนซ์กำลังแทนที่องค์ประกอบ DOM พารามิเตอร์นี้จะระบุว่าจะอัพเดตองค์ประกอบด้วยเนื้อหาอินสแตนซ์หรือไม่

ดังนั้นเพื่อหลีกเลี่ยงข้อผิดพลาดให้โทรทำลายก่อนที่จะลบองค์ประกอบ textarea ออกจาก DOM หรือเรียกใช้ destory (จริง) เพื่อหลีกเลี่ยงการพยายามอัปเดตองค์ประกอบ DOM ที่ไม่มีอยู่จริง

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

(ใช้เวอร์ชัน 3.6.2 พร้อมอะแดปเตอร์ jQuery)


3

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน:

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

ตรวจสอบให้แน่ใจว่ารหัส "ยกเลิก" ของคุณเรียกสิ่งที่คล้ายกันนี้! ปัญหาของฉันคือการยกเลิกของฉันไม่ได้โทรไปทำลาย :)
ROunofF

2
CKEDITOR.instances = new Array();

ฉันใช้สิ่งนี้ก่อนการโทรเพื่อสร้างอินสแตนซ์ (การโหลดต่อหน้า) ไม่แน่ใจว่าสิ่งนี้มีผลต่อการจัดการหน่วยความจำอย่างไรและอะไรไม่ สิ่งนี้จะใช้ได้ผลก็ต่อเมื่อคุณต้องการแทนที่อินสแตนซ์ทั้งหมดบนเพจ


1
ฉันลองวิธีแก้ปัญหาทั้งหมดในหน้านี้ ... สำหรับสภาพแวดล้อมของฉันนี่เป็นวิธีเดียวที่ใช้งานได้ (แต่ใช้งานไม่ได้ใน IE9 เท่านั้น FF ของฉัน) ... ไม่แน่ใจว่าทำไมคนอื่นถึงไม่ทำ แต่หลังจาก 1 ชั่วโมง จากการลองผิดลองถูกนี่เป็นทางออกเดียวที่ใช้ได้ผลสำหรับฉัน ขอบคุณที่โพสต์แอนดรูว์นี้
Ronedog

2

ฉันได้เตรียมโซลูชันของตัวเองตามรหัสข้างต้นทั้งหมด

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

มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน

บางครั้งหลังจากการร้องขอ AJAX มีโครงสร้าง DOM ที่ไม่ถูกต้อง สำหรับ instace:

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

ซึ่งจะทำให้เกิดปัญหาเช่นกันและ ckEditor จะไม่ทำงาน ดังนั้นตรวจสอบให้แน่ใจว่าคุณมีโครงสร้าง DOM ที่ถูกต้อง


2

ฉันมีปัญหาเดียวกันกับอินสแตนซ์ฉันมองหาทุกที่และในที่สุดการใช้งานนี้ก็ใช้ได้ผลสำหรับฉัน:



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


2

คุณสามารถลบอินสแตนซ์ ckeditor ใดก็ได้โดยลบเมธอด ckeditor อินสแตนซ์จะเป็น id หรือชื่อของ textarea

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

1

อันที่จริงการลบคลาส ".ckeditor" ออกจากโค้ดของคุณช่วยแก้ปัญหาได้ พวกเราส่วนใหญ่ปฏิบัติตามตัวอย่างการรวม jQuery จากเอกสารของ ckeditor:

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

และคิดว่า "... บางทีฉันสามารถกำจัดหรือส่วน" .jquery_ "ได้

ฉันเสียเวลาไปกับการปรับแต่งฟังก์ชันโทรกลับ (เพราะ {skin: 'office2003'} ใช้งานได้จริง) ในขณะที่ปัญหามาจากที่อื่น

ฉันคิดว่าเอกสารควรระบุว่าไม่แนะนำให้ใช้ "ckeditor" เป็นชื่อคลาสเนื่องจากเป็นคีย์เวิร์ดที่สงวนไว้

ไชโย


1

ฉันได้เรียนรู้ว่า

ลบ CKEDITOR.instances [editorName];

ด้วยตัวมันเองจริงๆแล้วเอาอินสแตนซ์ออก วิธีอื่น ๆ ทั้งหมดที่ฉันได้อ่านและเห็นรวมถึงสิ่งที่พบที่นี่ที่ stackoverflow จากผู้ใช้ไม่ได้ผลสำหรับฉัน

ในสถานการณ์ของฉันฉันใช้การโทร ajax เพื่อดึงสำเนาของเนื้อหาที่ล้อมรอบและ ปัญหาเกิดขึ้นเนื่องจากฉันใช้เหตุการณ์ jQuery .live เพื่อผูกลิงก์ "แก้ไขเอกสารนี้" จากนั้นใช้อินสแตนซ์ ckeditor หลังจากโหลด ajax สำเร็จ ซึ่งหมายความว่าเมื่อฉันคลิกลิงก์อื่นลิงก์ที่มีเหตุการณ์. live อื่นฉันต้องใช้ CKEDITOR.instances [editorName] ซึ่งเป็นส่วนหนึ่งของงานของฉันในการล้างหน้าต่างเนื้อหา (ถือแบบฟอร์ม) จากนั้นดึงเนื้อหาที่เก็บไว้อีกครั้ง ในฐานข้อมูลหรือทรัพยากรอื่น ๆ


1

ฉันมีปัญหาเดียวกันกับ jQuery Dialog

ทำไมต้องทำลายอินสแตนซ์ถ้าคุณแค่ต้องการลบข้อมูลก่อนหน้านี้?

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

1

ฉันเลือกที่จะเปลี่ยนชื่ออินสแตนซ์ทั้งหมดแทนการทำลาย / แทนที่ - เนื่องจากบางครั้งอินสแตนซ์ที่โหลด AJAX ไม่ได้แทนที่อินสแตนซ์บนแกนหลักของหน้า ... เก็บไว้ใน RAM ได้มากขึ้น แต่มีความขัดแย้งน้อยลงด้วยวิธีนี้

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

1

ฉันอยู่ในสถานการณ์ที่ฉันต้องควบคุมกล่องโต้ตอบวางไข่นั้นแต่ละกล่องต้องมี ckeditor ฝังอยู่ในกล่องโต้ตอบเหล่านี้ และมันก็เกิดขึ้นเช่นกันพื้นที่ข้อความใช้รหัสเดียวกัน (โดยปกตินี่เป็นวิธีปฏิบัติที่แย่มาก แต่ฉันมี jqGrids 2 ชิ้นหนึ่งในรายการที่ได้รับมอบหมายและอีกรายการที่ไม่ได้มอบหมาย) พวกเขามีการกำหนดค่าที่เหมือนกันเกือบทั้งหมด ดังนั้นฉันใช้รหัสทั่วไปเพื่อกำหนดค่าทั้งสองอย่าง

ดังนั้นเมื่อฉันโหลดไดอะล็อกสำหรับการเพิ่มแถวหรือเพื่อแก้ไขจาก jqGrid; ฉันต้องลบอินสแตนซ์ทั้งหมดของ CKEDITOR ในพื้นที่ข้อความทั้งหมด

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

    }
});

สิ่งนี้จะวนซ้ำในพื้นที่ข้อความทั้งหมดและหากมีอินสแตนซ์ CKEDITOR ให้ทำลายทิ้ง

หรือถ้าคุณใช้ jQuery แท้:

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

    }
});


0

ฉันมีปัญหาเดียวกันกับที่ฉันได้รับข้อยกเว้นการอ้างอิงที่เป็นโมฆะและคำว่า "null" จะปรากฏในตัวแก้ไข ฉันลองใช้วิธีแก้ปัญหาจำนวนหนึ่งรวมถึงการอัปเกรดตัวแก้ไขเป็น 3.4.1 ก็ไม่มีประโยชน์

ฉันต้องแก้ไขแหล่งที่มา ที่ประมาณบรรทัด 416 ถึง 426 ใน _source \ plugins \ wysiwygarea \ plugin.js จะมีตัวอย่างดังนี้:

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

ใน FF เป็นอย่างน้อย iframe ไม่ได้ถูกสร้างอินสแตนซ์อย่างสมบูรณ์ตามเวลาที่ต้องการ ฉันล้อมรอบฟังก์ชันที่เหลือหลังจากบรรทัดนั้นด้วยฟังก์ชัน 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
...

ตอนนี้ข้อความแสดงผลอย่างสม่ำเสมอในกล่องโต้ตอบโมดอล


0

เพื่อรองรับการโหลดแบบฟอร์ม (Ajax) แบบไดนามิก (โดยไม่มีการรีเฟรชหน้าระหว่าง) ซึ่งมีพื้นที่ข้อความที่เหมือนกัน (เรียกแบบฟอร์มเดียวกันอีกครั้ง) หรือ ID ที่แตกต่างกัน (แบบฟอร์มที่ยกเลิกการโหลดก่อนหน้านี้) และแปลงเป็นองค์ประกอบ CKEditor ฉันทำสิ่งต่อไปนี้ (โดยใช้ JQuery อะแดปเตอร์):

หลังจากเพจเสร็จสิ้นการเรียก Ajax ทุกครั้งที่ส่ง textarea ที่จะแปลงฉันจะโทรไปยังฟังก์ชันต่อไปนี้:

setupCKeditor()

ลักษณะเช่นนี้ (สมมติว่า textareas ของคุณถูกแปลงเป็น RTE มี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);

            });

    }


}

ฉันควรพูดถึงว่าบรรทัด:

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

สามารถ (และควร) เป็นเพียง:

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

อย่างไรก็ตามฉันพบว่าตัวแก้ไขมักจะแสดงเนื้อหาที่ถูกต้องเป็นเวลาหนึ่งวินาทีหลังจากการโหลดและพวกเขาจะทำให้ตัวแก้ไขเนื้อหาที่ต้องการว่างเปล่า ดังนั้นบรรทัดที่มีรหัสเรียกกลับจึงบังคับให้เนื้อหา CKEditor เหมือนกับเนื้อหา textarea ต้นทาง ทำให้เกิดการสั่นไหวเมื่อใช้งาน หากหลีกเลี่ยงการใช้งานได้ให้ทำ ..


0

ฉันมีปัญหาเดียวกันกับ Jackboberg ฉันใช้การโหลดแบบฟอร์มไดนามิกในไดอะล็อก jquery จากนั้นแนบวิดเจ็ตต่างๆ (datepickers, ckeditors ฯลฯ ... ) และฉันลองวิธีแก้ปัญหาทั้งหมดที่ระบุไว้ข้างต้นไม่มีวิธีใดได้ผลสำหรับฉัน

ด้วยเหตุผลบางประการ ckeditor แนบเฉพาะครั้งแรกที่ฉันโหลดแบบฟอร์มครั้งที่สองฉันได้รับข้อความแสดงข้อผิดพลาดเดียวกันกับที่แจ็คโบเบอร์กทำ

ฉันได้วิเคราะห์โค้ดของฉันแล้วและพบว่าหากคุณแนบ ckeditor ใน "กลางอากาศ" ซึ่งในขณะที่เนื้อหาแบบฟอร์มยังไม่ถูกวางลงในกล่องโต้ตอบ ckeditor จะไม่แนบการเชื่อมโยงอย่างถูกต้อง นั่นคือเนื่องจาก ckeditor ติดอยู่ใน "กลางอากาศ" ครั้งที่สองที่คุณแนบใน "กลางอากาศ" ... poof ... เกิดข้อผิดพลาดเนื่องจากอินสแตนซ์แรกไม่ได้ถูกลบออกจาก DOM อย่างถูกต้อง

นี่คือรหัสของฉันที่ระบุข้อผิดพลาด:

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

นี่คือการแก้ไขที่ได้ผล:

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

0

ฉันพบสิ่งเดียวกันนี้ทั้งหมดและปัญหาคือปลั๊กอินนับจำนวนคำใช้เวลาเริ่มต้นนานเกินไป 30+ วินาที ผู้ใช้จะคลิกเข้าไปในมุมมองที่แสดง ckeditor จากนั้นยกเลิกด้วยเหตุนี้จึงต้องโหลดหน้าใหม่ลงในโดม ปลั๊กอินถูกร้องเรียนเนื่องจาก iframe หรือ contentWindow ใด ๆ ที่ชี้ไปไม่สามารถมองเห็นได้อีกต่อไปเมื่อถึงเวลาที่พร้อมที่จะเพิ่มตัวเองลงใน contentWindow คุณสามารถตรวจสอบได้โดยคลิกเข้าไปในมุมมองของคุณจากนั้นรอให้ Word Count ปรากฏที่ด้านล่างขวาของตัวแก้ไข ถ้าคุณยกเลิกตอนนี้คุณจะไม่มีปัญหา หากคุณไม่รอคุณจะได้รับข้อผิดพลาด i.contentWindow เป็น null ในการแก้ไขเพียงแค่ลบปลั๊กอิน:

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

หากคุณต้องการตัวนับคำให้ลงทะเบียนสำหรับเหตุการณ์วางและคีย์อัพในตัวแก้ไขด้วยฟังก์ชันที่นับจำนวนคำ


0

สำหรับผู้ที่ใช้ "อะแดปเตอร์" jquery และมีปัญหา (เหมือนที่ฉันเคยเป็น) เนื่องจากวิธีแก้ปัญหาที่แฮ็ก แต่ใช้งานได้ดีคือการทำสิ่งนี้:

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

});

ประเด็นสำคัญคือส่วนนี้:

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

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

วิธีนี้ช่วยแก้ปัญหาการมองไม่เห็นข้อความตัวแก้ไขในครั้งถัดไปที่คุณเปิดกล่องโต้ตอบ ฉันรู้ว่านี่เป็นการแฮ็กมาก แต่เมื่อพิจารณาว่าสิ่งเหล่านี้ส่วนใหญ่จะใช้กับเครื่องมือของผู้ดูแลระบบฉันไม่คิดว่าจะเป็นเรื่องใหญ่อย่างที่มันเป็นปกติ .. และมันก็ใช้ได้ผลดังนั้นหวังว่ามันจะช่วยใครบางคนได้บ้าง เวลา;)


0

นี่คือรหัสที่ใช้งานได้อย่างสมบูรณ์สำหรับ jquery .load () api และ ckeditor ในกรณีของฉันฉันกำลังโหลดหน้าที่มี ckeditor เป็น div พร้อมเอฟเฟกต์ jquery ฉันหวังว่ามันจะช่วยคุณได้

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

0

มันค่อนข้างง่าย ในกรณีของฉันฉันใช้วิธี jquery ด้านล่างซึ่งจะทำลายอินสแตนซ์ ckeditor ระหว่างการโหลดหน้าเว็บ นี่เป็นการหลอกลวงและแก้ไขปัญหา -

วิธี 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

       });

แค่นั้นแหละ. ฉันหวังว่ามันจะช่วยคุณได้

ไชโย Sirish


0

ฟังก์ชั่นนี้ใช้ได้กับฉันใน CKEditor เวอร์ชัน 4.4.5 แต่ไม่มีการรั่วไหลของหน่วยความจำ

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

// เรียกใช้ฟังก์ชันนี้ตามด้านล่าง

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

CKEditor_Render(id);

0

CKeditor 4.2.1

มีคำตอบมากมายที่นี่ แต่สำหรับฉันฉันต้องการอะไรมากกว่านั้น (สกปรกไปหน่อยถ้าใครสามารถปรับปรุงได้โปรดทำ) สำหรับฉัน MODALs ที่ปัญหาของฉัน

ฉันกำลังเรนเดอร์ CKEditor ในรูปแบบโมดอลโดยใช้ Foundation ตามหลักการแล้วฉันจะทำลายตัวแก้ไขเมื่อปิดตัวลง แต่ฉันไม่ต้องการยุ่งกับ Foundation

ฉันเรียกว่าลบฉันลองลบและวิธีอื่น แต่นี่คือสิ่งที่ฉันตัดสินในที่สุด

ฉันใช้ textarea เพื่อเติมข้อมูลไม่ใช่ DIV

โซลูชันของฉัน

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

นี่เป็นวิธีการของฉันในการส่งคืนการจัดรูปแบบเฉพาะของฉันซึ่งคุณอาจไม่ต้องการ

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.