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

标签 javascript drag-and-drop ckeditor ckeditor4.x

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

首先,拖放到编辑器中可以正常使用 dataTransfer 等。但每当我必须销毁并重新创建编辑器的实例时,拖放内容就会停止按预期工作。

我直接从CKEditor's SDK page about DnD integration修改了示例代码,您可以在其中看到正在重现的问题。 (我只是减少了示例以使其更加简洁,并在列表底部添加了“销毁并重新创建”按钮。)

无法让它在 JSFiddle 中工作,对此感到抱歉,但这是代码:

        'use strict';

        var CONTACTS = [{
          name: 'Huckleberry Finn',
          tel: '+48 1345 234 235',
          email: '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="731b5d151a1d1d33160b121e031f165d101c1e" rel="noreferrer noopener nofollow">[email protected]</a>',
          avatar: 'hfin'
        }, {
          name: 'D\'Artagnan',
          tel: '+45 2345 234 235',
          email: '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bedadfcccadfd9d0dfd0fedbc6dfd3ced2db90ddd1d3" rel="noreferrer noopener nofollow">[email protected]</a>',
          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 和 justify 似乎一直运行良好,但 Drag_list 却不然。

有谁知道为什么会这样吗?我需要做什么才能在新创建的 CKEditor 实例中拖放内容(例如示例的 hcard)?

提前致谢。

最佳答案

它看起来像是编辑器核心中的一个令人讨厌的错误。我查了一下,报了票:https://dev.ckeditor.com/ticket/14339在问题得到修复之前,我所能建议的就是在编辑器游戏中重新附加 dragstart 事件。您可以将: CKEDITOR.document.getById('contactList').on('dragstart', ... ); 放入插件 init 方法中。进行此类更改后,拖放应该可以工作,但 dragstart 将被多次触发。您可以分离 dragstart 事件,然后再次附加它,一切都应该正常工作。

关于javascript - CKEDITOR 拖放插件集成在编辑器实例被销毁并重新创建后停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34899462/

相关文章:

javascript - 来自雅虎财经 API 的 400 错误请求

javascript - HTML Webpack 插件未创建正确的 index.html 文件

javascript - 如何在php中的不同链接中添加不同的评论框?

javascript - 如何通过 AJAX 拖放动态生成的表

ckeditor - ckeditor 上的临时禁用按钮

javascript - Vue js 无法获取配置值

java - Android:拖放多个图像

javascript - JavaScript 中的鼠标事件问题

javascript - CKeditor 无法正常工作

javascript - 将原子内容插入 CKEditor