CKEDITOR 拖放插件集成在编辑器实例销毁并重新创建后停止工作

CKEDITOR Drag and drop plugin integration stops working after editor instance is destroyed and recreated

本文关键字:新创建 创建 停止工作 集成 插件 拖放 编辑器 实例 CKEDITOR      更新时间:2023-09-26

我在尝试使用 CKEditor 的拖放集成时遇到了很多麻烦。

首先,拖放到编辑器中可以很好地处理数据传输和所有内容。但是,每当我必须销毁并重新创建编辑器的实例时,拖放内容都会停止按预期工作。

我直接从 CKEditor 的 SDK 页面修改了关于 DnD 集成的示例代码,您可以在其中看到重现的问题。(我只是减少了示例,使其更加简洁,并在列表底部添加了"销毁并重新创建"按钮。

无法让它在 JSFiddle 中工作,很抱歉,但这是代码:

        'use strict';
        var CONTACTS = [{
          name: 'Huckleberry Finn',
          tel: '+48 1345 234 235',
          email: 'h.finn@example.com',
          avatar: 'hfin'
        }, {
          name: 'D''Artagnan',
          tel: '+45 2345 234 235',
          email: 'dartagnan@example.com',
          avatar: 'dartagnan'
        }];
        CKEDITOR.disableAutoInline = true;
        CKEDITOR.plugins.add('drag_list', {
          requires: 'widget',
          init: function(editor) {
            editor.widgets.add('drag_list', {
              allowedContent: true,
              pathName: 'drag_list',
              upcast: function(el) {
                return el.name == 'table' && el.hasClass('product_widget');
              }
            });
            editor.addFeature(editor.widgets.registered.drag_list);
            editor.on('paste', function(evt) {
              var contact = evt.data.dataTransfer.getData('contact');
              if (!contact) {
                return;
              }
              evt.data.dataValue =
                '<span class="h-card">' +
                '<a href="mailto:' + contact.email + '" class="p-name u-email">' + contact.name + '</a>' +
                ' ' +
                '<span class="p-tel">' + contact.tel + '</span>' +
                '</span>';
            });
          }
        });
        CKEDITOR.document.getById('contactList').on('dragstart', function(evt) {
          var target = evt.data.getTarget().getAscendant('div', true);
          CKEDITOR.plugins.clipboard.initDragDataTransfer(evt);
          var dataTransfer = evt.data.dataTransfer;
          dataTransfer.setData('contact', CONTACTS[target.data('contact')]);
          dataTransfer.setData('text/html', target.getText());
          if (dataTransfer.$.setDragImage) {
            dataTransfer.$.setDragImage(target.findOne('img').$, 0, 0);
          }
        });
        CKEDITOR.inline('editor1', {
          extraPlugins: 'drag_list,sourcedialog,justify'
        });
        function destroy_recreate() {
          for (var instance in CKEDITOR.instances) {
            console.log(CKEDITOR.instances[instance])
            CKEDITOR.instances[instance].destroy();
          }
          CKEDITOR.inline('editor1', {
            extraPlugins: 'drag_list,sourcedialog,justify'
          });
        }
.columns {
  background: #fff;
  padding: 20px;
  border: 1px solid #E7E7E7;
}
.columns:after {
  content: "";
  clear: both;
  display: block;
}
.columns > .editor {
  float: left;
  width: 65%;
  position: relative;
  z-index: 1;
}
.columns > .contacts {
  float: right;
  width: 35%;
  box-sizing: border-box;
  padding: 0 0 0 20px;
}
#contactList {
  list-style-type: none;
  margin: 0 !important;
  padding: 0;
}
#contactList li {
  background: #FAFAFA;
  margin-bottom: 1px;
  height: 56px;
  line-height: 56px;
  cursor: pointer;
}
#contactList li:nth-child(2n) {
  background: #F3F3F3;
}
#contactList li:hover {
  background: #FFFDE3;
  border-left: 5px solid #DCDAC1;
  margin-left: -5px;
}
.contact {
  padding: 0 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.contact .u-photo {
  display: inline-block;
  vertical-align: middle;
  margin-right: 10px;
}
#editor1 .h-card {
  background: #FFFDE3;
  padding: 3px 6px;
  border-bottom: 1px dashed #ccc;
}
#editor1 {
  border: 1px solid #E7E7E7;
  padding: 0 20px;
  background: #fff;
  position: relative;
}
#editor1 .h-card .p-tel {
  font-style: italic;
}
#editor1 .h-card .p-tel::before,
#editor1 .h-card .p-tel::after {
  font-style: normal;
}
#editor1 .h-card .p-tel::before {
  content: "(☎ ";
}
#editor1 .h-card .p-tel::after {
  content: ")";
}
#editor1 h1 {
  text-align: center;
}
#editor1 hr {
  border-style: dotted;
  border-color: #DCDCDC;
  border-width: 1px 0 0;
}
<script src="http://cdn.ckeditor.com/4.5.5/standard-all/ckeditor.js"></script>
<div class="columns">
  <div class="editor">
    <div cols="10" id="editor1" name="editor1" rows="10" contenteditable="true">
      <h3>Drop stuff here then press the Destroy/Recreate button and try again.</h3>
    </div>
  </div>
  <div class="contacts">
    <h3>List of Droppable Contacts</h3>
    <ul id="contactList">
      <li>
        <div class="contact h-card" data-contact="0" draggable="true" tabindex="0">
          <img src="http://sdk.ckeditor.com/samples/assets/draganddrop/img/hfin.png" alt="avatar" class="u-photo">Huckleberry Finn
        </div>
      </li>
      <li>
        <div class="contact h-card" data-contact="1" draggable="true" tabindex="0">
          <img src="http://sdk.ckeditor.com/samples/assets/draganddrop/img/dartagnan.png" alt="avatar" class="u-photo">D'Artagnan
        </div>
      </li>
    </ul>
    <button class='destroy_recreate' onclick='destroy_recreate()'>Destroy and recreate editors</button>
  </div>
</div>

其他插件,如sourcedialog和juste似乎运行良好,但drag_list却没有。

有谁知道为什么会这样?我必须做什么才能在新创建的 CKEditor 实例中拖放内容,例如示例的 hcard?

提前谢谢。

它看起来像编辑器核心中的一个令人讨厌的错误。我检查了一下并报告了一张票:https://dev.ckeditor.com/ticket/14339 在票证修复之前,我所能建议的就是在编辑器重新创建dragstart重新附加该事件。你可以把:CKEDITOR.document.getById('contactList').on('dragstart', ... );放在插件init方法里面。在这种更改之后,拖放应该可以工作,但dragstart将被多次触发。您可以分离dragstart事件,在再次附加它之前,一切都应该正常工作。