【问题标题】:CKEditor loop only works on the last instanceCKEditor 循环仅适用于最后一个实例
【发布时间】:2017-03-01 23:14:22
【问题描述】:

我正在尝试在页面上的所有 CKEditor 文本区域上设置焦点事件。这是加载到 jQuery 文档准备好的代码:

for (var i in CKEDITOR.instances) {
    alert(CKEDITOR.instances[i].name);
    CKEDITOR.instances[i].on('focus', function() {
        alert(CKEDITOR.instances[i].name);
        remove_invalidation(CKEDITOR.instances[i].name);
    });
}

(注意:remove_invalidation() 是我编写的一个函数,它只是删除了 textarea 上的一些 CSS 格式。它应该不会影响问题。)

我添加了几个警报以查看发生了什么。因此,正如预期的那样,当文档就绪事件启动此代码时,我立即得到一个接一个的文本区域,其中包含每个 CKEditor 文本区域的名称。这行得通。

但是,当我在任何文本区域内单击以使它们获得焦点时,警报总是会弹出页面上最后一个文本区域的名称。

【问题讨论】:

  • 运行console.log(CKEDITOR.instances);时在Firebug或其他控制台中有什么?

标签: jquery focus ckeditor instance


【解决方案1】:

试试这个:

for (var i in CKEDITOR.instances) {
    (function(i){
        alert(CKEDITOR.instances[i].name);
        CKEDITOR.instances[i].on('focus', function() {
           alert(CKEDITOR.instances[i].name);
           remove_invalidation(CKEDITOR.instances[i].name);
        });
    })(i);
}

问题是您在每个焦点事件中使用相同的 i,并且 i 被递增到最后一个编辑器的值。将代码放在立即执行的函数中,通过为代码提供自己的作用域来解决这个问题。

【讨论】:

  • 谢谢!我和一位同事也刚刚想出了一个类似的解决方案。我们使用了与上面相同的代码,但在焦点事件函数中,我们将“CKEDITOR.instances[i]”更改为“this”,它的工作原理与您描述的相同。
【解决方案2】:

解释MDN article Closures(“在循环中创建闭包:一个常见错误”部分):

循环创建了许多闭包,但每个闭包都共享 相同的单一词法环境,其中有一个变量 值(i)。 i 的值是在 on('focus') 回调被执行。因为循环已经运行了 当然到那时,i 变量(由所有人共享 闭包)一直指向CKEDITOR.instances中的最后一个条目 列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 2016-08-24
    • 2013-10-30
    相关资源
    最近更新 更多