问题
I'm having quite a bit of trouble while trying to use CKEditor's drag and drop integration.
At first, dragging and dropping into the editor works allright with dataTransfer and all. But whenever I have to destroy and recreate an instance of the editor, dragging and dropping content stops working as expected.
I have modified the sample code directly from CKEditor's SDK page about DnD integration, where you can see the issue being reproduced. (I just reduced the example as to make it more succint and added the "Destroy and recreate" button at the bottom of the list.)
Could not get it to work in JSFiddle, so sorry about that, but here's the code:
'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>
Other plugins like sourcedialog and justify seem to keep working well, but drag_list does not.
Does anyone know why this is happening? What do I have to do to be able to drag and drop content such as the example's hcards in a newly created CKEditor instance?
Thanks in advance.
回答1:
It looks like a nasty bug in the editor core. I checked it and reported a ticket: https://dev.ckeditor.com/ticket/14339 Until the ticket will be fixed, all I can suggest is to reattach dragstart
event on the editor recreation. You can put: CKEDITOR.document.getById('contactList').on('dragstart', ... );
inside the plugin init
method. After such change drag and drop should work, but dragstart
will be fired multiple times. You can detach the dragstart
event, before you attach it again end everything should work fine.
来源:https://stackoverflow.com/questions/34899462/ckeditor-drag-and-drop-plugin-integration-stops-working-after-editor-instance-is