CKEditor 4和jQuery UI sortable在排序后删除内容

问题描述 投票:7回答:7

我遇到了CKEditor 4和jQuery UI的可排序方法的问题,如果我对具有CKEditor实例的容器进行排序,它会删除该值并抛出错误“未捕获的TypeError:无法调用未定义的方法'getSelection'”。它也使编辑器无法编辑。我能够在CKEditor 3中解决这个问题,其中包括以下黑客攻击之一:CKEditor freezes on jQuery UI Reorder

在查看Chrome DOM检查器时,似乎会删除iframe的内容。

以下是原始测试代码:


    <html>
    <head>
        <title>test</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/jquery-ui.min.js"></script>
        <script src="ckeditor.js"></script>
        <script type="text/javascript">
        $(function(){

            var tmpStore = {};
            $('#sortable').sortable({
                cursor: 'move',

                // Hack that use to work on V3 but not on V4:
                // https://stackoverflow.com/questions/3379653/ckeditor-freezes-on-jquery-ui-reorder
                start:function (event,ui) {
                    $('textarea').each(function(){
                        var id = $(this).attr('id');
                        tmpStore[id] = CKEDITOR.instances[id].getData();
                    })
                 },
                stop: function(event, ui) { 
                    $('textarea').each(function(){
                        var id = $(this).attr('id');
                        CKEDITOR.instances[id].setData(tmpStore[id]);
                    })
                  }
            });
            $('textarea').each(function(){
                var ckId = $(this).attr('id');
                config = {};
                CKEDITOR.replace(ckId, config);
            })
        })

        
        
        li { padding: 10px; width: 800px; height: 300px; }
        
    </head>
    <body>
        <ul id="sortable">
            <li><textarea id="test1" name="test1">test1</textarea></li>
            <li><textarea id="test2" name="test1">test2</textarea></li>
            <li><textarea id="test3" name="test1">test3</textarea></li>
        </ul>
    </body>
    </html>

jquery-ui ckeditor jquery-ui-sortable
7个回答
3
投票

一旦修改了底层DOM结构,就必须重新创建CKEditor。在editor.getData()之前使用editor.destroy()保存编辑器数据,并在创建新实例后使用editor.setData( data )恢复内容。没有其他方法可以解决这个问题,因为CKEditor强烈依赖于DOM结构。


3
投票

我遇到了同样的问题,并根据这里的答案进行了修复。请参阅下面的小提琴

问题:https://jsfiddle.net/33qt24L9/1/

  $(function() {
        $( "#sortable" ).sortable({
      placeholder: "ui-state-highlight"
    });

       CKEDITOR.replace( 'editor1' );
       CKEDITOR.replace( 'editor2' );
       CKEDITOR.replace( 'editor3' );
       CKEDITOR.replace( 'editor4' );

  });

已解决的问题:https://jsfiddle.net/57djq2bh/2/

  $(function() {
        $( "#sortable" ).sortable({
      placeholder: "ui-state-highlight",

             start: function (event, ui) 
        {
            var id_textarea = ui.item.find(".ckeditor").attr("id");
            CKEDITOR.instances[id_textarea].destroy();
        },
        stop: function (event, ui) 
        {
            var id_textarea = ui.item.find(".ckeditor").attr("id");
            CKEDITOR.replace(id_textarea);
        }           

    });

       CKEDITOR.replace( 'editor1' );
       CKEDITOR.replace( 'editor2' );
       CKEDITOR.replace( 'editor3' );
       CKEDITOR.replace( 'editor4' );

  });

编辑:如果像我一样,你有每个编辑器的单独配置这里的更新代码,将有助于:

start: function (event, ui)
        {
            $('.wysiwyg', ui.item).each(function(){
                var tagId = $(this).attr('id');
                var ckeClone = $(this).next('.cke').clone().addClass('cloned');
                ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
                CKEDITOR.instances[tagId].destroy();
                $(this).hide().after(ckeClone);
            });
        },

        stop: function(event, ui) {
            // for each textarea init ckeditor anew and remove the clone
            $('.wysiwyg', ui.item).each(function(){
                var tagId = $(this).attr('id');
                CKEDITOR.replace(tagId, ckeConfigs[tagId]);
                $(this).next('.cloned').remove();
            });
        }

感谢:https://github.com/trsteel88/TrsteelCkeditorBundle/issues/53


0
投票

我通过在打开jquery对话框后实例化CKEditor来解决这类问题


0
投票

下面的代码对我有用,我们必须在启动时销毁编辑器并在拖动结束时重新创建它,获取来自以下数据的textarea的值:

jQuery(function($) 
{
    var panelList = $("#nameofyourdiv");
    panelList.sortable(
    {
        handle: ".classofyourdivforsorting", 
        start: function (event, ui) 
        {
            var id_textarea = ui.item.find("textarea").attr("id");
            CKEDITOR.instances[id_textarea].destroy();
        } 
        stop: function (event, ui) 
        {
            var id_textarea = ui.item.find("textarea").attr("id");
            CKEDITOR.replace(id_textarea);
        }           
    });
});

希望它可以帮助某人。


0
投票

我和CKEDITOR有类似的问题,下面的代码对我有用。销毁Ckeditor实例并删除Ckeditor,当拖动结束时再次用Ckeditor替换当前的textarea

 $("#sortable").sortable({
        items: '.dynamic',
        start: function (event , ui) {

                var editorId = $(ui.item).find('.ckeditor').attr('id');// get the id of your Ckeditor
                editorInstance = CKEDITOR.instances[editorId]; // Get the Ckeditor Instance
                editorInstance.destroy(); // Destroy it
                CKEDITOR.remove(editorId);// Remove it

        },
        stop: function(event, ui) { 
                var editorId = $(ui.item).find('.ckeditor').attr('id');// Get the Id of your Ckeditor 
                CKEDITOR.replace(editorId);// Replace it
            }
        } 

    });
    $("#sortable").disableSelection();

这里#sortable是可排序的DIV的id,'。dynamic'是分配给有资格排序的DIV的类,'。fixitor'是Textarea的类。

我从Here得到了我的解决方案,希望这有助于将来的某个人。


0
投票

删除CKEditor启动可排序

var ckeConfigs = [];
$('.ui-sortable').sortable({
 start:function (event,ui) {
  $('.lineItemCommentBox', ui.item).each(function(){
    var tagId = $(this).attr('id');
        ckeConfigs[tagId] = CKEDITOR.instances[tagId].config;
    CKEDITOR.instances[tagId].destroy();
  });
 },
 stop: function(event, ui) {
  $('.lineItemCommentBox', ui.item).each(function(){
   var tagId = $(this).attr('id');
   CKEDITOR.replace(tagId, ckeConfigs[tagId]);
  });
 }
});

-1
投票

我只是使用ckeditorOff()和ckeditorOn()函数在移动过程中保存数据和re / de-instance ckeditor实例。

$('#sortable').sortable({
    cursor: 'move',
    start:function (event,ui) {
        if(typeof ckeditorOff=='function')ckeditorOff();
    },
    stop: function(event, ui) { 
        if(typeof ckeditorOn=='function')ckeditorOn();
    } 
});

我把typeof ckeditorOff语句用来使代码与ckeditor的未来版本兼容,以防他们决定删除这两个函数。

© www.soinside.com 2019 - 2024. All rights reserved.