ckeditor onKeyUp event how?

2019-05-24 08:13发布

问题:

This code piece must copy text from textarea text to textarea text_hidden, this code work without ckeditor

onKeyUp="document.getElementById('text_hidden').value = this.value;

but when ckeditor enabled

onKeyUp="document.getElementById('text_hidden').value = this.value; not work.

How to fix this ?

<textarea name="text" id="text" rows="6" cols="80"  onKeyUp="document.getElementById('text_hidden').value = this.value;" ></textarea></p>

<textarea name="text_hidden" id="text_hidden" rows="6" cols="80" ></textarea>

<script>
        CKEDITOR.replace( 'text' ,
        {   
    allowedContent: true,
    enterMode: CKEDITOR.ENTER_BR,

    });
        CKFinder.SetupCKEditor( editor, '/ckfinder/' );
        config.startupPath = "/files/";
</script>

回答1:

Here is my demo for CKEditor-to-textarea sync and vice versa: https://jsfiddle.net/ty5ks393/1/. Type in one of the three white boxes and see the content replicate across all four containers.

It uses Bootstrap to keep things tidy and shows both the classic and inline CKEditors. The pertinent parts (without external resources, comments and console.logs) are extracted here:

    <div class="row">
        <div class="col-sm-3">
            <h2>TEXTAREA</h2>
            <textarea id="textarea" class="box"></textarea>
        </div>
        <div class="col-sm-3">
            <h2>CK EDITOR INLINE</h2>
            <div contenteditable="true" id="contentedit" class="box"></div>
        </div>
        <div class="col-sm-3">
            <h2>CK EDITOR</h2>
            <textarea id="ckeditor" class="box"></textarea>
        </div>
        <div class="col-sm-3">
            <h2>RESULT DIV</h2>
            <div id="result" class="box"></div>
        </div>  
    </div>

And the jQuery:

    $(function() {
        CKEDITOR.disableAutoInline = true;
        var ce = CKEDITOR.inline("contentedit", {
            removePlugins: 'toolbar'
        });
        var ck = CKEDITOR.replace('ckeditor').on('change', function(e) {
            if (document.activeElement.nodeName == "IFRAME") {
                var thisHTML = e.editor.getData();
                var tempDiv = $('<div>').html(thisHTML);
                thisText = tempDiv.text();
                $('#textarea').val(thisText);
                $('#contentedit, #result').html(thisHTML);  
            }
        });

        var timer;

        $('#textarea').keyup(function() {
            var _this = this;
            clearTimeout(timer);
            timer = setTimeout(function() {
                var thisText =$(_this).val().replace(/\n/g, "<br/>");
                $('#result, #contentedit').html(thisText);
                CKEDITOR.instances.ckeditor.setData(thisText);
            }, 200);
        });

        $('#contentedit').keyup(function(e) {
            var _this = this;
            clearTimeout(timer);
            timer = setTimeout(function() {
                var thisHTML = $(_this).html();
                var tempDiv = $('<div>').html(thisHTML.replace(/\<\/p\>/g,"</p>\n\n"));
                thisText = tempDiv.text();
                $('#textarea').val(thisText);
                $('#result').html(thisHTML);
                CKEDITOR.instances.ckeditor.setData(thisHTML);
            }, 200);
        });
    });

So I use a timeout to avoid the bottlenecking that comes with keyup when using setData(). And I detect whether I am in an IFRAME to make sure I don't bounce content changes back out of the CKEditor when I've changed the content from one of the other containers using setData().

I hope it helps some of you.



回答2:

After searching around, I found an article (ckeditor-keyup-event) stating that CKEditor api do not support "keyup" event. Only on "key" method that listens to keypress event is supported.

The article author uses editor.document.on('keyup') in a callback on editor.setData(), which is only available after initialisation.

I prefer to attach the required keyup event during initialisation instead since his workaround does not work for my use case. I changed your code as shown below which works well for me although it is not actually attaching to a keyup event.

CKEDITOR.replace( 'text' ,
{   
    allowedContent: true,
    enterMode: CKEDITOR.ENTER_BR,
}).on('key',
    function(e){
        setTimeout(function(){
            document.getElementById('text_hidden').value = e.editor.getData();
        },10);
    }
);

Without the setTimeout() function, getData() will not grab the last keystroke.



回答3:

If you want to synch WYSIWYG content with the textarea just tell the on change event as option to update the underlying element.

CKEDITOR.replace('editor', {
    on: {
          change: function() {
              this.updateElement();    
          }
    }
});