无法为动态生成的Ckeditor分配Id

时间:2012-07-19 09:15:05

标签: jquery iframe ckeditor

我有很多ckeditor实例在一个页面中动态生成,而在ckeditor的instanceReady函数中,我得到了每个ckeditor的实例,从那里我得到iFrame的引用,我分配了一个id。现在,在我说iFrameDocument.getElementById(assignedIframeId)后分配id后,我无法找到iFrame。这是我的代码:

<html>
<body>
    <!-- This is the template. The div tag with class="contents" will be replaced with CKEditor -->
    <script type="text/html" id="PS_ItemViewModel-template">
        <div id="mgrComments" class="document comment-region">
            <div class="contents" data-bind="html : mgrComments"></div>
        </div>
    </script>
            <!-- looping the template based on the number of items -->
            <div class="ps-item-container" data-bind="foreach : psItems">
       <div data-bind="template : {'name' : 'PS_ItemViewModel-template'}, event 
:   {psItemSetupEditor : _setupEditor, psItemRefreshEditor : _refreshEditor}"></div>                                                    
             </div>
</body>
</html>

// In the javascript file ...
    self._setupEditor = function(data, event){
    var domNode = event.currentTarget;
    self.editor = self._injectEditorInstance($(domNode).find('div#mgrComments   div.contents'), self.mgrComments, self.headerNode, self.criterionNodes);
}

self._injectEditorInstance = function(commentNode, initialText, headerNode, criterionNodes) {
    $('div#editor-toolbar').show();

    commentNode.ckeditor(function(){
        console.log("Inside commentNode.ckeditor ...");
        var editor = this;

        this.setData(initialText, function(){
            //Handles direct changes to editor contents
            editor.on('setData', function() {
                self.editorChangeHandler(editor);
            });

            //Handles paste
            editor.on('paste', function() {
                console.log("In paste event ...");
                self.editorChangeHandler(editor);
            });
        });
    }, {customConfig : '/simple_eval/js/ckeditor/SimpleEvalEditorConfig.js'});

    return commentNode.ckeditorGet();   
};

$(document).ready(function() {  


CKEDITOR.on("instanceReady", function(e) {
    console.log("In instanceReady ...................................");
    var assignedId  =   e.editor.name + "jspell";
    $("#cke_contents_" + e.editor.name+" iframe").attr("id", assignedId);
    var iframeDoc   =   null;
    $('#'+assignedId).each( 
                function(){ iframeDoc=this.contentWindow.document;}
                );
            console.log(" innerDoc Element = "+iframeDoc.getElementById(assignedId));
    fieldsToCheck[fieldsToCheck.length] = [iframeDoc, assignedId];
    jspellInit();
   });


});

var fieldsToCheck = new Array();
function getSpellCheckArray() { 
console.log("In getSpellCheckArray ...................................");
   return fieldsToCheck;
}   

在上面的代码中,当我说console.log(“innerDoc Element =”+ iframeDoc.getElementById(assignedId));它打印出null,这意味着在iframe文档中找不到该元素。 有人可以建议我如何将id分配给ckeditor的iframe,以便可以使用iframe分配的id来检索它。

感谢。

1 个答案:

答案 0 :(得分:0)

您可以为每个实例的HTML <body>分配一个ID,并使用它来获取内容块。

因为您正在创建多个实例,所以我假设您使用的是CKEDITOR.replaceAll()

创建实例时,您可以为每个内容正文分配ID。我通过在<body> ID中添加“正文”来创建<textarea> ID。

CKEDITOR.replaceAll( function(textarea, config) {    
  // Assume all textareas to be edited will have class "ckeditor"
  if (!(textarea.className=="testing")) {
    return false;
  }

  config.bodyId = textarea.id + 'body';
});

然后在“instanceReady”函数中,获取实例名称(与textarea ID相同)并向其添加“body”,这将为您提供包含要拼写的文本的内容区域的ID检查。

您可以使用e.editor.document获取iFrame文档。

var fieldsToCheck;

CKEDITOR.on("instanceReady", function(e) {
  console.log(e.editor.name);
  console.log(e.editor.document);

  var assignedId = e.editor.name + "body";
  fieldsToCheck[fieldsToCheck.length] = [e.editor.document, assignedId];
});

如果在触发拼写检查时需要设置fieldsToCheck数组,则可以遍历实例数组。

$("#test_button").click(function(){
  var fieldsToCheck;

  $.each(CKEDITOR.instances, function () {
    console.log(this.name);
    console.log(this.document);

    var assignedId = this.name + "body";
    fieldsToCheck[fieldsToCheck.length] = [this.document, assignedId];
  });
});

7月26日更新

我已准备好您的文档部分并进行了一些更改。我注释掉了我替换的项目,并将新版本放在注释掉的部分下面。正在为iframe分配ID。我不知道为实例分配了哪些名称,但只要它们是唯一的,ID就是唯一的。

可能不太明显,但是为每个创建的实例单独调用CkEditor on.instanceReady方法,因此您可能希望将jspellInit()函数调用移到instanceReady函数之外并且将所有实例添加到数组后,让它与fieldsToCheck数组一起使用。

我还添加了一些包含实际CkEditor对象的console.log()语句。您可以在需要更改内容时查看可用的属性和方法。

请务必阅读最后的注意

$(document).ready(function() {  
    var fieldsToCheck=new Array();
    var editorCount = 0;

    CKEDITOR.on("instanceReady", function(e) {
        console.log("In instanceReady ...................................");
        console.log(e);
        console.log(e.editor);

        var assignedId  =   e.editor.name + "jspell";

    //    $("#cke_contents_" + e.editor.name+" iframe").attr("id", assignedId);
        $("#cke_contents_" + e.editor.name+" iframe").context.activeElement.id = assignedId;

    //    var iframeDoc   =   null;    
        var iframeDoc = $('#'+assignedId)[0].contentDocument;

    //    $('#'+assignedId).each( 
    //        function(){ iframeDoc=this.contentWindow.document;}
    //    );


    //    This won't work, iframeDoc is inside the iFrame with id=assignedId
    //    console.log(" innerDoc Element = "+iframeDoc.getElementById(assignedId));
        console.log(iframeDoc);

        var editorBody = e.editor.document.getBody();
        editorBody.setAttribute("id", "TESTsetBODYid"+editorCount);
        console.log(editorBody);
        editorCount += 1;

        fieldsToCheck[fieldsToCheck.length] = [iframeDoc, assignedId];
        console.log(fieldsToCheck);
        jspellInit();
    });
});

注意

我没有使用过jSpell,所以我不确定你真正需要放入fieldsToCheck数组,但是现在iframeDoc包含完整的HTML代码({{1} })在iframe中找到。 <head> and <body>变量包含iframe的ID。

在我看来,要进行拼写检查,你需要assignedId元素的内容,所以我在创建<body>数组之前包含了getBody()方法的示例。我还提供了一个如何设置正文ID的示例。