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

Posted

技术标签:

【中文标题】CKEditor 4 和 jQuery UI 可排序在排序后删除内容【英文标题】:CKEditor 4 and jQuery UI sortable removes content after sorting 【发布时间】:2013-02-14 00:19:54 【问题描述】:

我遇到了 CKEditor 4 和 jQuery UI 的 sortable 方法的问题,如果我对具有 CKEditor 实例的容器进行排序,它会删除该值并抛出错误“Uncaught TypeError: Cannot call method 'getSelection' of undefined ”。它还使编辑器无法编辑。我能够在 CKEditor 3 中通过以下技巧之一解决这个问题: CKEditor freezes on jQuery UI Reorder

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

下面是粗略的测试代码:

测试 【参考方案1】:

我遇到了同样的问题,并根据此处的答案进行了修复。请看下面的小提琴

问题: 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

【讨论】:

【参考方案2】:

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

【讨论】:

使用 destroy() 并重新创建实例似乎可以解决问题。 有没有简单的方法来保留撤销/重做数据?【参考方案3】:

下面的代码对我有用,我们必须在启动时销毁编辑器,并在拖动结束时重新创建它,获取来自数据的 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);
                   
    );
);

希望对某人有所帮助。

【讨论】:

【参考方案4】:

删除CKEditor start Sortable

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]);
  );
 
);

【讨论】:

【参考方案5】:

我已经通过在打开 jquery 对话框后实例化 CKEditor 解决了此类问题

【讨论】:

【参考方案6】:

我遇到了与 CKEDITOR 类似的问题,下面的代码对我有用。销毁 Ckeditor 实例并删除 Ckeditor 并在拖动结束时再次用 Ckeditor 替换当前文本区域

 $("#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 的类,'.ckeditor' 是 Textarea 的类。

我从 Here 获得了我的解决方案,希望这对将来的某人有所帮助。

【讨论】:

【参考方案7】:

我只是使用 ckeditorOff() 和 ckeditorOn() 函数在移动过程中保存数据和重新/取消实例化 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 的未来版本兼容,以防他们决定删除这两个功能。

【讨论】:

CKEditor 是否提供了特定的“ckeditorOff”和“ckeditorOn”功能? 不,我只是按原样粘贴代码。我认为 ckeditorOff 和 On 是全局命令。我认为他们不会在不久的将来移除它们。 ckeditorOff() 和 ckeditorOn()?它们是 ckeditor 原生的。当您包含源代码时,它们会由 ckeditor js 自动定义。 不幸的是,他们不是。只需尝试在source 中查找它们。虽然缩小了函数名称必须在某个地方,但它们不是。 好的,请告诉我您正在使用哪个版本的 ckeditor,我会制作一个适用于您正在使用的版本的 sol。我使用的是 wordpress ckeditor 插件附带的 ckeditor。我使用的主题是动态创建搞砸 ckeditor 的评论字段。我想我可以发布 ckeditorOn / Off 的定义,这样其他人就不必受苦了。

以上是关于CKEditor 4 和 jQuery UI 可排序在排序后删除内容的主要内容,如果未能解决你的问题,请参考以下文章

CKEditor 5 和 jQuery 验证错误

用 jQuery 同步 CKEditor 和 TEXTAREA

使用 Jquery 从 CKEditor 检测 onChange 事件

在jquery中添加多个CKEditor实例

UI标签库专题十二:JEECG智能开发平台 ckeditor(ckeditor插件标签)

带有 jQ​​uery UI 对话框、拼写检查和按钮在第二次单击时不起作用的 CKEditor