使用jQuery从CKEditor的iframe中获取内容

27

我有一个使用CKEditor *(FCKEditor v3)编辑内容的自定义CMS。在基于AJAX的提交之前,我还使用jQuery Validation插件检查所有字段是否有误。我使用serialize()函数将数据传递给PHP后端。

问题是,serialize成功地获取了除CKEditor中实际输入内容以外的所有字段。与其他所见即所得编辑器一样,该编辑器也会在现有文本框上覆盖一个iframe。如果序列化忽略iframe并仅查看文本框中的内容,则找不到内容,从而返回空白内容体。

我的解决方法是在CKEditor的onchange事件上创建钩子,并同时更新文本框(CKEDITOR.instances.[textboxname].getData()返回内容)或其他任何隐藏字段,以反映编辑器中进行的更改。

然而,由于CKEditor仍处于测试阶段且严重缺乏文档,我找不到适当的API调用来实现这一点。

有人知道如何处理吗?


1
我已经弄清楚了从 iframe 中获取内容的部分: $( '#cke_contents_body iframe' ).contents().find( 'body' ).html()... 最接近可直接寻址的元素是一个带有 ID 为“cke_contents_body”的 td 元素。CKEditor 使用该 td 包装 iframe。 - miCRoSCoPiC_eaRthLinG
还有一个问题,如何通过挂钩CKEditor的更改事件自动更新文本框中的数据。有什么想法吗?有人吗? - miCRoSCoPiC_eaRthLinG
1
新的CKEditor版本已经解决了这个问题。 - Ivan
11个回答

36

另一个通用的解决方案是在尝试提交表单时运行以下代码:

for ( instance in CKEDITOR.instances )
            CKEDITOR.instances[instance].updateElement();

这将强制表单中的所有 CKEDITOR 实例更新其各自的字段


1
@J.J. 是的。这是JavaScript代码,应该在表单的“submit”事件上运行(或在此之前的任何时间)。 - Gabriele Petrioli
Gaby,又名G. Petrioli - 谢谢。 - Bajrang

7

很酷的东西。谢谢。这确实让它变得容易了。 - miCRoSCoPiC_eaRthLinG
此链接已于2018年9月14日失效。 - HungryBeagle

6

今天我一直在试图解决这个问题。我意识到以上代码无法正常工作的原因是因为当引用文档属性时,CKEditor实例尚未准备好。因此,您必须调用“instanceReady”事件,并在其中使用文档事件,因为在此之前它不存在。

这个例子可能适合你:

CKEDITOR.instances["editor1"].on("instanceReady", function()
{
//set keyup event
this.document.on("keyup", CK_jQ);

 //and paste event
this.document.on("paste", CK_jQ);
});

function CK_jQ()
{

    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
}

$("#editor1").val(CKEDITOR.instances.editor1.getData()); 执行成功,谢谢。 - Limitless isa

3
这应该可以做到...
CKEDITOR.instances["editor1"].document.on('keydown', function(event)
{
    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
});

CKEDITOR.instances["editor1"].document.on('paste', function(event)
{
    CKEDITOR.tools.setTimeout( function()
    { 
        $("#editor1").val(CKEDITOR.instances.editor1.getData()); 
    }, 0);
});

编辑:添加了更新文本框的部分,以便在粘贴后进行更新...


谢谢您的回复...但它一直告诉我:"CKEDITOR.instances.editor1.document未定义"!! - miCRoSCoPiC_eaRthLinG
顺便问一下,你能解释一下为什么在这里要使用setTimeout而不是直接在按键时复制内容吗? - miCRoSCoPiC_eaRthLinG
2
请将editor1替换为您的文本框名称。setTimeout是为了确保我们在按键添加之后获取内容,而不是之前。 - Stobor
你是指的keyup事件吗? - Spons
@spons 事后看来,keyup可能更好。 - Stobor

2
我用以下方法成功了:

console.log(CKEDITOR.instances.editor1.getData());

1

contentDom事件对我有用,而instanceReady事件则没有... 我真的很想知道这些事件是什么,但我认为它们是专有的...

var editor = CKEDITOR.replace('editor');

CKEDITOR.instances.editor.on("instanceReady", function(){
    this.on('contentDom', function() {
        this.document.on('keydown', function(event) {
            CKEDITOR.tools.setTimeout( function(){ 
                $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
            }, 1);
        });
    });
    this.on('contentDom', function() {
        this.document.on('paste', function(event) {
            CKEDITOR.tools.setTimeout( function(){ 
                $(".seldiv").html(CKEDITOR.instances.editor.getData()); 
            }, 1);
        });
    });
    edits_clix();
    var td = setTimeout("ebuttons()", 1);
})

你的回答在我调试/重写近4个小时后拯救了我。我的代码在使用“instanceReady”时大部分情况下运行良好,但在通过 AJAX 载入的内容上根本不起作用。只是想说谢谢。 - narx

1

我采用了稍微不同的方法,我认为使用 ckeditor 的更新功能会更好,而且由于已经使用了 keyup,所以不需要超时。

CKEDITOR.instances["editor1"].on("instanceReady", function()
{
//set keyup event
this.document.on("keyup", CK_jQ);

 //and paste event
this.document.on("paste", CK_jQ);
}

function CK_jQ()
{
   CKEDITOR.instances.editor1.updateElement(); 
}

1

1

CKEDITOR.instances.wc_content1.getData() 将返回 ckeditor 数据
CKEDITOR.instances.wc_content1.setData() 将设置 ckeditor 数据


0

我认为用户在询问序列化方面的问题,我曾经尝试将表单序列化以进行提交,但遇到了很多问题。

以下是对我有效的方法:

$(document).ready(function() {
$('#form').submit(function(){
if ( CKEDITOR.instances.editor1.getData() == '' ){
    alert( 'There is no data available' );//an alert just to check if its working
}else{
    var editor_data = CKEDITOR.instances.editor1.getData();
    $("#editor1").val(editor_data); //at this point i give the value to the textarea
    $.ajax({ 
                    //do your ajax here  

                     });

        }
return false;
    });
 });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接