Search code examples
javascripthtmlckeditorckeditor4.x

CKEditor selectionChange is not working as it should be


I am using CKEditor as a part of my Python, Flask project. I am trying to pass text which is selected with mouse to another "textarea".

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>CKEditor Örneği</title>
    <script src="https://cdn.ckeditor.com/4.16.2/standard/ckeditor.js"></script>
</head>

<body>

    <textarea id="editor1" name="editor1"></textarea>
    <br>
    <textarea id="selectedTextDisplay" name="selectedTextDisplay" readonly></textarea>

    <script>
        CKEDITOR.replace('editor1');
        
        function showSelectedText() {
            var editor = CKEDITOR.instances.editor1;
            var selectedText = editor.getSelection().getSelectedText();
            document.getElementById('selectedTextDisplay').value = selectedText;
        }

        CKEDITOR.instances.editor1.on('selectionChange', function (evt) {
            showSelectedText();
        });
    </script>

</body>
</html>

I have the code above, and the problem is that when I select a text, it doesn't directly pass it to other textarea. I have to click somewhere else in the editor, or switch between tabs or programs on my computer, and when I return to my webpage, then the copying process happens.

I have tried to use "mouseup" like this but did not help.

CKEDITOR.instances.editor1.on('mouse', function (evt) {
            showSelectedText();
        });

Solution

  • The following works (tbh, I'm cheating a bit).

    CKEDITOR.instances.editor1.on('contentDom', function () {
      this.document.on('selectionchange', showSelectedText);
    });
    

    What this does is:

    1. Wait for the CKEditor instance to initialize. It's kind of like DOMContentLoaded, but in this case it's referring to the loading of the content of CKEditor - it's actually creating an iframe, and populating it with content.
    2. After the instance has been initialized, an event listener is attached to its DOM, and that event listener is doing what you want it to - monitor when the selection is changed. Also - notice the lack of capitalization in selectionchange. This is because I'm using the selectionchange event from the Selection API.

    A working fiddle can be found here (apologies for providing an off-site resource, but the stacksnippet was reporting CORS errors, and I didn't know how to overcome them).