开发者

CKEditor loop only works on the last instance

I'm trying to set a focus event on all my CKEditor textareas on the page. Here's the code that loads on jQuery document ready:

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);
    });
}

(Note: remove_invalidation() is a function I wrote that just removes some CSS formatting on the textarea. It shouldn't affect the problem.)

I added a couple alerts to see what was happening. So, right away, as expected, when the document ready event kicks off this code, I get one textarea after another with the names of each of the CKEditor textareas. That works.

But, when I click inside any of the textareas to give them 开发者_StackOverflowfocus, the alert always pops up the name of the last textarea on the page.


try this:

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);
}

the issue was you are using the same i within each on focus event, and that i was getting incremented to the value for the last editor. Placing the code within an immediately executing function solves this problem by giving the code it's own scope.


Paraphrasing the MDN article Closures (section "Creating closures in loops: A common mistake"):

A number of closures have been created by the loop, but each one shares the same single lexical environment, which has a variable with changing values (i). The value of i is determined when the on('focus') callbacks are executed. Because the loop has already run its course by that time, the i variable (shared by all closures) has been left pointing to the last entry in the CKEDITOR.instances list.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜