Цикл CKEditor работает только с последним экземпляром

Я пытаюсь установить событие фокуса для всех моих текстовых областей 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() — это написанная мной функция, которая просто удаляет некоторое форматирование CSS в текстовой области. Это не должно влиять на проблему.)

Я добавил пару предупреждений, чтобы увидеть, что происходит. Итак, сразу же, как и ожидалось, когда событие готовности документа запускает этот код, я получаю одну текстовую область за другой с именами каждой из текстовых областей CKEditor. Это работает.

Но когда я щелкаю внутри любой из текстовых областей, чтобы сфокусировать их, в предупреждении всегда появляется имя последней текстовой области на странице.


person Nick Petrie    schedule 21.09.2011    source источник
comment
Что у вас в Firebug или другой консоли при запуске console.log(CKEDITOR.instances);?   -  person atma    schedule 21.09.2011


Ответы (2)


попробуй это:

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 в каждом событии фокуса, и что я увеличивался до значения для последнего редактора. Размещение кода внутри немедленно исполняемой функции решает эту проблему, предоставляя коду собственную область видимости.

person Kevin B    schedule 21.09.2011
comment
Спасибо! Мы с коллегой тоже только что придумали похожее решение. Мы использовали тот же код, что и выше, но внутри функции события фокуса мы изменили CKEDITOR.instances[i] на это, и это сработало по той же причине, что вы описали. - person Nick Petrie; 22.09.2011

Перефразируя замыкания статьи MDN (раздел "Создание замыканий в циклах") : Распространенная ошибка"):

Цикл создал несколько замыканий, но каждое из них имеет одну и ту же единую лексическую среду, в которой есть переменная с изменяющимися значениями (i). Значение i определяется при выполнении обратных вызовов on('focus'). Поскольку к тому времени цикл уже завершился, переменная i (общая для всех замыканий) осталась указывающей на последнюю запись в списке CKEDITOR.instances.

person codeape    schedule 01.03.2017