如何避免交换节点后 CKEditor 实例死亡?
How to avoid CKEditor instance death after swap node?
我有一个 HTML table,每行有一个 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、Chrome61 @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>
您必须先销毁实例,交换行,然后重新创建实例。当销毁实例时,它们的文本区域会更新为它们的数据,因此当重新创建它们时,数据不会丢失。
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'));
我有一个 HTML table,每行有一个 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,{});
该调用在此堆栈跟踪中结束:
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、Chrome61 @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>
您必须先销毁实例,交换行,然后重新创建实例。当销毁实例时,它们的文本区域会更新为它们的数据,因此当重新创建它们时,数据不会丢失。
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'));