如何在页面中的多个 CKEditor 实例上触发点击事件?

问题描述

我不认为我不能在不解释很多情况的情况下发布此内容,所以请耐心等待。

我有一个包含多个 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.logckInstances.push(...) 之间添加了很多 ckEditables.push(...) 并且我不再收到该错误,我不知道为什么。但是后来我收到了 Cannot read property 'attachListener' of undefined错误,尽管——我认为——contentDom 处理程序应该能够成功访问这个变量。

我在想这个问题,也许前一个问题也是如此,可能是因为 contentDom 在该变量存在之前触发。但是,我确定我对此还不够了解。

我尝试了其他几种类似的方法,但没有任何效果

  • 最后,由于 contentDom 事件在编辑器内容准备好时被触发,我想我可以通过首先创建 CKEDITOR 实例和可编辑的数组,然后循环它们,附加侦听器来使其工作一次一个

这里有一件重要的事情:由于我无法在包含可编辑内容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 (将#修改为@)