交换节点后如何避免CKEditor实例死亡?

时间:2018-05-07 14:58:50

标签: javascript html dom ckeditor

我有一个HTML表,每行有一个CKEditor实例,一切正常,直到我在两行之间交换位置。在交换之后,不显示值,并且方法setData的任何使用都以JS错误结束。

基本结构是:

<tr id=1>
  <td>...</td>
  <td>ckeditor1</td>
</tr>
.
.
<tr id=n>
  <td>...</td>
  <td>ckeditorn</td>
</tr>

用于交换节点的方法是

Node.prototype.swapNode = function (node) {
        var nextSibling = this.nextSibling;
        var parentNode = this.parentNode;
        node.parentNode.replaceChild(this, node);
        parentNode.insertBefore(node, nextSibling);  
    };

所以,我调用Node1.swapNode(Node2),CKEditor失去它的值,然后试图通过CKEditor.instances[1].setData(data,{});

在CKEditor实例上再次强制值

该调用以此堆栈跟踪结束:

   TypeError: this.document.getWindow(...).$ is undefined  ckeditor.js:427:29
        CKEDITOR.dom.selection.prototype.getNative http://localhost/js/packages/ckeditor/ckeditor.js:427:29
        CKEDITOR.dom.selection http://localhost/js/packages/ckeditor/ckeditor.js:425:54
        CKEDITOR.editor.prototype.getSelection http://localhost/js/packages/ckeditor/ckeditor.js:422:319
        CKEDITOR.plugins.undo.Image http://localhost/js/packages/ckeditor/ckeditor.js:1077:358
        b.prototype.save http://localhost/js/packages/ckeditor/ckeditor.js:1072:24
        .init/< http://localhost/js/packages/ckeditor/ckeditor.js:1068:269
        h http://localhost/js/packages/ckeditor/ckeditor.js:10:68
        CKEDITOR.event.prototype</<.fire</< http://localhost/js/packages/ckeditor/ckeditor.js:11:428
        CKEDITOR.editor.prototype.fire http://localhost/js/packages/ckeditor/ckeditor.js:13:67
        .setData http://localhost/js/packages/ckeditor/ckeditor.js:261:79

在FF 52,Opera 52,Chrome 61 @OpenSuse 42.3上进行测试

是否可以通过其他方式实现交换而不会丢失值?或者至少没有以错误结束?

此致

段:

Node.prototype.swapNode = function (node) {
            var nextSibling = this.nextSibling;
            var parentNode = this.parentNode;
            node.parentNode.replaceChild(this, node);
            parentNode.insertBefore(node, nextSibling);  
};

var element1 = new     CKEDITOR.dom.element(document.getElementById('doc_content1'));
CKEDITOR.replace(element1);

var element2 = new CKEDITOR.dom.element(document.getElementById('doc_content2'));
CKEDITOR.replace(element2);
<html>
<head>
 <script src="https://cdn.ckeditor.com/4.9.2/full/ckeditor.js"></script>
</head>
<body> 
<form>
<table>
<tbody>
<tr id='1'>
    <td><input name="doc_title1" type="text"></td>
    <td><textarea id="doc_content1" name="doc_content1" ></textarea></td>
    <td><input type="button" onclick="javascript: this.parentNode.parentNode.swapNode(document.getElementById('2'));" value='change to 2'></td>
</tr>
<tr id='2'>
    <td><input name="doc_title2" type="text"></td>
    <td><textarea id="doc_content2"  name="doc_content2"></textarea></td>
    <td><input type="button" onclick="javascript: this.parentNode.parentNode.swapNode(document.getElementById('1'));" value='change to 1'>
    </td>
</tr>
</tbody>
</form>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

您必须首先销毁实例,交换行然后重新创建实例。在销毁实例时,它们的textareas会更新其数据,因此在重新创建它们时,数据不会丢失。

Node.prototype.swapNode = function (node) {
    var firstInstance = 'doc_content' + node.id;
    var secondInstance = 'doc_content' + this.id;
    CKEDITOR.instances[firstInstance].destroy();
    CKEDITOR.instances[secondInstance].destroy();
    var nextSibling = this.nextSibling;
    var parentNode = this.parentNode;
    node.parentNode.replaceChild(this, node);
    parentNode.insertBefore(node, nextSibling);  
    CKEDITOR.replace(document.getElementById(firstInstance));
    CKEDITOR.replace(document.getElementById(secondInstance));
};

CKEDITOR.replace(document.getElementById('doc_content1'));
CKEDITOR.replace(document.getElementById('doc_content2'));