我正在尝试在页面上的所有CKEditor textareas上设置焦点事件。这是加载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 textareas名称的textarea。这很有效。
但是,当我点击任何textareas内部给他们焦点时,警报总是会弹出页面上最后一个textarea的名称。
答案 0 :(得分:7)
试试这个:
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,并且我正在增加到最后一个编辑器的值。将代码放在一个立即执行的函数中可以通过给代码提供自己的范围来解决这个问题。
答案 1 :(得分:1)
释义MDN article Closures("在循环中创建闭包:常见的错误"):
循环创建了许多闭包,但每个闭包共享
相同的单一词汇环境,具有变化的变量
值(i
)。 i
的值在确定时确定
on('focus')
回调被执行。因为循环已经运行了
那个时候,i
变量(由所有人共享
已经指向CKEDITOR.instances
中的最后一个条目
列表。