问题描述
我不认为我不能在不解释很多情况的情况下发布此内容,所以请耐心等待。
我有一个包含多个 CKEditor 实例的页面,我需要在用户单击任何编辑器实例时进行检测。我正在遵循已接受的答案 here 和文档 here,但是我在将侦听器附加到我的所有实例时遇到了一些麻烦。
目前,我正在用一个加载 27 个 CKEditor 实例的页面对此进行测试。
这就是我所尝试的:
-
首先,我尝试用
CKEDITOR.instances
循环for... of
,但后来我发现CKEDITOR.instances
不可迭代。 -
其次,我尝试通过以下方式循环
CKEDITOR.instances
中的键:
for (key in CKEDITOR.instances) {
CKEDITOR.instances[key].on('contentDom',function() {
CKEDITOR.instances[key].editable().attachListener(
CKEDITOR.instances[key].editable(),'click',function() {
console.log('You clicked ' + key);
}
);
});
}
这个问题是只有当我单击最后一个编辑器时才会触发该事件,并且它会触发 27 次(每个实例一次)。我可以看到最后一个 CKEditor 实例最终附加了所有实例的侦听器,而其他实例没有。我不明白为什么会发生这种情况,因为我将侦听器附加到每个实例。
我尝试了同样的方法,但为 CKEDITOR.instances[key].editable()
声明了一个变量,但发生了同样的情况。我以为如果我在 contentDom
处理程序内部或外部声明变量(具有不同的作用域),我会得到不同的行为,但也会发生同样的情况。
var currentEditable;
for (key in CKEDITOR.instances) {
CKEDITOR.instances[key].on('contentDom',function() {
currentEditable = CKEDITOR.instances[key].editable();
currentEditable.attachListener(
currentEditable,function() {
console.log('You clicked ' + key);
}
);
});
}
- 第三,我尝试遍历
CKEDITOR.instances
的键,但这次使用的是数组,如下所示:
var ckKeys = Object.keys(CKEDITOR.instances);
// To store the CKEDITOR instances separately and avoid conflicts
var ckInstances = [];
// To store CKEDITOR edtiables separately and avoid conflicts
var ckEditables = [];
var instancesLength = ckKeys.length;
var instCount = 0;
for (instCount; instCount < instancesLength; instCount++) {
ckInstances.push(CKEDITOR.instances[ckKeys[instCount]]);
ckEditables.push(ckInstances[instCount].editable());
ckInstances[instCount].on('contentDom',function() {
ckEditables[instCount].attachListener(
ckEditables[instCount],function() {
console.log('You clicked ' + (instCount+1));
}
);
});
}
但这并没有真正起作用,并且以我不理解的方式运行。推送与当前迭代对应的值后,即使 Cannot read property 'editable' of undefined
不是未定义的,我也收到错误消息 ckInstances[instCount]
;我知道是因为我将它记录到控制台并打印了预期的对象。我在 console.log
和 ckInstances.push(...)
之间添加了很多 ckEditables.push(...)
并且我不再收到该错误,我不知道为什么。但是后来我收到了 Cannot read property 'attachListener' of undefined
的错误,尽管——我认为——contentDom
处理程序应该能够成功访问这个变量。
我在想这个问题,也许前一个问题也是如此,可能是因为 contentDom
在该变量存在之前触发。但是,我确定我对此还不够了解。
这里有一件重要的事情:由于我无法在包含可编辑内容的 load
元素上触发 <iframe>
事件,所以我必须首先检查所有其中有内容以确保它们都已加载。 (除了 CKEditor 引入的元素,我没有 <iframe>
元素)。因此,如果我在确保它们全部加载后创建这个 CKEDITOR 实例和可编辑对象数组,那么我认为我真的不需要 contentDom
事件。考虑到这一点,我尝试了以下操作:
ckInstances = [];
ckEditables = [];
var instancesLength = ckKeys.length;
var instCount = 0;
// First create the arrays of CKEDITOR instances and editables.
for (instCount; instCount < instancesLength; instCount++) {
ckInstances.push(CKEDITOR.instances[ckKeys[instCount]]);
ckEditables.push(ckInstances[instCount].editable());
}
// I can use this same variable to loop over these arrays
instCount = 0;
for (instCount; instCount < instancesLength; instCount++) {
ckEditables[instCount].attachListener(
ckEditables[instCount],function() {
console.log('You clicked ');
console.log(this);
}
);
}
这非常适合在所有实例上触发点击事件,最后一个除外。我不知道为什么,因为如果我将相关变量记录到控制台,我可以看到最后一个也被处理了。
文档说 here attachListener()
也可用于将侦听器附加到另一个对象,“例如附加到文档。”
所以我在创建数组后尝试了这个:
for (instCount; instCount < instancesLength; instCount++) {
ckEditables[instCount].attachListener(
ckInstance[instCount].document,function() {
console.log('You clicked ');
console.log(this);
console.log(this['$'].children[0].children[0].childNodes[0].attributes[0].nodeValue);
}
);
}
这成功地在每个实例上触发了事件,但是 this
是嵌入的 HTML 文档,要访问任何子字符串或数字,我可以从中获取实际单击了哪个编辑器实例,我必须这样做很长时间东西 this['$'].children[0].children[0].childNodes[0].attributes[0].nodeValue
,在我的情况下打印 'Rich Text Editor,id_form-0-text'
(当然,表单索引随实例而变化)。它可以满足我的需要,但似乎必须做太多事情,我想知道如何以更好、可能更有效的方式做到这一点。
我还想知道 contentDom
事件究竟意味着什么,以及为什么我一直在应该存在的变量中获取这些 undefined
值。我假设 contentDom
意味着 <iframe>
元素已加载,但我不确定因为我得到的行为,我想我得到了那些 undefined
值是因为我在听 { {1}} 事件在 for 循环中,但我不确定。此外,如果不在 contentDom
的处理程序中附加侦听器会产生什么后果?特别是,考虑到我将动态添加和删除实例,并将为每个新添加的实例附加侦听器。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)