События прослушивателя сбрасываются при изменении setData и режима с помощью CKEditor

Всякий раз, когда мой сценарий вызывает setData или меняет режим («источник», «WYSIWYG»), прослушиватели для назначенных мной событий больше не вызываются.

Исследования показали мне почему, и я экспериментировал с предлагаемыми решениями (CKEDITOR.setData предотвращает присоединение событий с функцией .on), в том числе из официальной документации (http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDom), но ни одно из разрешений не работает для меня, как указано в документации, и я понятия не имею, почему.

Кому-нибудь еще здесь удалось решить эту проблему? Если да, то буду очень благодарен узнать как.

В настоящее время мы используем версию 4.5.10 CKEditor.

Благодарим вас заранее. Кен.

Пример:

// Works until setData() is called or until the view mode is changed ("WYSIWYG", "SOURCE).

ev.editor.document.on( 'keydown', function( evt )
{
    console.log("Key Down");
});

// This appears to be the recommended resolution however, this does not
    // work for me even prior to setData() being called of the view mode being changed.

    editor.on( 'contentDom', function() {
    var editable = editor.editable();

    editable.attachListener( editor.document, 'keydown', function() {
    console.log("Key Down"); // Never executed
        } );
    } );

ОБНОВЛЕНИЕ: это решение (предложенное Декелем) выглядит так, как будто оно должно работать. Однако я подозреваю, что не реализовал его правильно, поэтому событие Key Down не срабатывает. Любые мысли по этому поводу:

for (var i in CKEDITOR.instances) {
    CKEDITOR.instances[i].on('contentDom', function() {
        CKEDITOR.instances[i].document.on('keydown', function(event) {
            console.log('key down')
        });
    });
}

ОБНОВЛЕНИЕ: пример полного кода. Событие больше не срабатывает:

    <html>

<textarea name="editor1">
</textarea>

<textarea name="editor2">
</textarea>

<textarea name="editor3">
</textarea>

</html>

<script>

CKEDITOR.replace( 'editor1', {
  allowedContent: true
});

CKEDITOR.replace( 'editor2', {
  allowedContent: true
});

CKEDITOR.replace( 'editor3', {
  allowedContent: true
});

for (var i in CKEDITOR.instances) {
    CKEDITOR.instances[i].on('contentDom', function() {
        CKEDITOR.instances[i].document.on('keydown', function(event) {
            console.log('key down')
        });
    });
}

</script>

person SystemsGo    schedule 21.09.2016    source источник
comment
Добавьте пример...   -  person Dekel    schedule 21.09.2016
comment
// Работает до вызова setData() или до изменения режима просмотра (WYSIWYG, SOURCE). ev.editor.document.on('keydown', function(evt) { console.log(Key Down); }); // Похоже, это рекомендуемое разрешение, однако // оно не работает для меня даже до вызова setData() для изменения режима просмотра. editor.on('contentDom', function() { var editable = editor.editable(); editable.attachListener( editor.document, 'keydown', function() { console.log(Key Down); // Никогда не выполнялось } ); } );   -  person SystemsGo    schedule 22.09.2016
comment
Извиняюсь за формат. Я новенький здесь. Как мне получить новые строки в примере?   -  person SystemsGo    schedule 22.09.2016
comment
Просто отредактируйте исходный вопрос.   -  person Dekel    schedule 22.09.2016
comment
И рабочий пример (jsfiddle.net/so-snippet гораздо лучше).   -  person Dekel    schedule 22.09.2016
comment
Большое спасибо Декель.   -  person SystemsGo    schedule 22.09.2016
comment
Что касается вашего обновления - пожалуйста, предоставьте полный рабочий пример (для этого вы можете использовать jsfiddle.net)   -  person Dekel    schedule 22.09.2016


Ответы (1)


Потребовалось некоторое время, чтобы понять, в чем проблема, но я думаю, что это решение, которое вы ищете.

Вам нужно прикреплять событие keydown каждый раз, когда DOM готов. Для этого вам нужно прослушать событие contentDom редактора, а затем зарегистрировать событие keydown в документе редактора.

CKEDITOR.instances.editor1.on( 'contentDom', function() {
    CKEDITOR.instances.editor1.document.on('keydown', function(event) {
        console.log('key down')
    });
});

В этом примере editor1 — это имя экземпляра ckeditor.

Вы можете проверить этот рабочий пример:
https://jsfiddle.net/gad701dc/

Если у вас есть несколько экземпляров, вам нужно будет перебрать их и добавить к каждому из них:

for (var i in CKEDITOR.instances) {
    CKEDITOR.instances[i].on('contentDom', function() {
        // The variable *this* here refers to the current instance of the ckeditor
        this.document.on('keydown', function(event) {
            console.log('key down')
        });
    });
}

Вам нужно получить доступ к соответствующему редактору, вы должны сделать это с this вместо CKEDITOR.instances[i], потому что переменная i изменится до того, как будет сделан вызов функции обратного вызова.

person Dekel    schedule 22.09.2016
comment
Отличный рабочий пример, спасибо. Используется несколько экземпляров редактора, и я обычно использую CKEDITOR.currentInstance. Однако теперь это отображается как неопределенное. Я попытался добавить ваш код в событие instanceReady, но currentInstance по-прежнему отображается как неопределенное. Есть мысли по этому поводу? - person SystemsGo; 22.09.2016
comment
Обновил ответ, проверьте дополнение в конце - person Dekel; 22.09.2016
comment
Спасибо Декель. Я ценю быстрый ответ. Я ответил через свой оригинальный пост. - person SystemsGo; 22.09.2016
comment
Просто напоминание, что у меня это еще не работает. Спасибо. - person SystemsGo; 23.09.2016
comment
Невозможно помочь, не зная, в чем проблема. Создайте jsfiddle со своим кодом, продемонстрируйте проблему... - person Dekel; 23.09.2016
comment
Программа, частью которой он является, огромна. Я не писал код, и у меня нет ко всему этому доступа. Проблема в том, что событие не запускается с использованием кода, показанного в конце моего OP. - person SystemsGo; 23.09.2016
comment
Если вы проверите ссылку в моем примере, вы увидите, что она работает. Если ваш код я написал каким-то другим способом, возможно, вам придется что-то изменить. Я не знаю, какую ошибку вы получаете/каковы ваши имена переменных, если у вас есть ошибки кода и так далее... - person Dekel; 23.09.2016
comment
Извиняюсь за поздний ответ, болел последние 5 дней. Я снял отметку с ответа как правильный, так как для этого вопроса было открыто более одной вкладки, и, увидев несделанную версию вопроса, я снова щелкнул ее. Я предполагаю, что развалил это. Я решу это через минуту. Что касается проблемы невозможности заставить код работать, я попытаюсь обновить ваш jsfiddle, поскольку я не смог найти необходимый URL-адрес, чтобы заставить CKEditor работать в моей версии. Спасибо. - person SystemsGo; 27.09.2016
comment
Неудивительно, что я не смог обновить ваш jsfiddle, поэтому я добавил полный пример в свой OP. В результате событие никогда не появляется. Есть идеи по поводу этого Декеля? - person SystemsGo; 27.09.2016
comment
Я не вижу полного примера в тебе, ОП. Пожалуйста, проверьте еще раз (я вижу только код javascript, который, как вы сказали, не работает... в то время как в моем примере он работает отлично), поэтому я предполагаю, что у вас есть какая-то другая ошибка. - person Dekel; 27.09.2016
comment
Извините, мне потребовалось некоторое время, чтобы правильно отформатировать код. - person SystemsGo; 27.09.2016
comment
Ok. нашел проблему в коде :) обновлю ответ в ближайшие несколько минут - person Dekel; 27.09.2016
comment
Прекрасная работа! Спасибо Декель. - person SystemsGo; 28.09.2016
comment
Конечно, добро пожаловать. Будет признателен за голосование по вопросу, когда у вас будет достаточно репутации (для этого вам нужно минимум 15). - person Dekel; 28.09.2016
comment
Я также откатил ваше обновление вопроса - в таком обновлении нет необходимости, поскольку есть ответ, помеченный как правильный ответ. - person Dekel; 28.09.2016