And*_*rew 1 drag-and-drop widget ckeditor
我有最新的 ckeditor 版本 4.5.7,带有拖放 API,我有一个情况,我需要将一个小部件从一个编辑器拖放到另一个编辑器。正如这张票所说,建议的功能是静默失败并且不执行任何操作。
就我而言,如果将小部件拖动到不同的编辑器,则需要复制小部件;如果将小部件拖动到同一编辑器中,则需要移动小部件。第二种情况已经在工作
关于如何做到这一点有什么想法吗?
editor.on( 'contentDom', function() {
var dropTarget = CKEDITOR.plugins.clipboard.getDropTarget( editor );
editor.editable().attachListener( dropTarget, 'drop', function( evt ) {
// The target may be some element inside the draggable div (e.g. the image), so get the div.h-card.
var target = evt.data.getTarget().getAscendant( 'div', true );
// Initialization of CKEditor data transfer facade is a necessary step to extend and unify native
// browser capabilities. For instance, Internet Explorer does not support any other data type than 'text' and 'URL'.
// Note: evt is an instance of CKEDITOR.dom.event, not a native event.
CKEDITOR.plugins.clipboard.initDragDataTransfer( evt );
var dataTransfer = evt.data.dataTransfer;
// Pass an object with contact details. Based on it, the editor#paste listener in the hcard plugin
// will create HTML to be inserted into the editor. We could set text/html here as well, but:
// * It is a more elegant and logical solution that this logic is kept in the hcard plugin.
// * We do not know now where the content will be dropped and the HTML to be inserted
// might vary depending on the drop target.
dataTransfer.setData( 'contact', CONTACTS[ target.data( 'contact' ) ] );
// We need to set some normal data types to backup values for two reasons:
// * In some browsers this is necessary to enable drag and drop into text in editor.
// * The content may be dropped in another place than the editor.
dataTransfer.setData( 'text/html', target.getText() );
} );
} );
Run Code Online (Sandbox Code Playgroud)
此外,如果 ckeditor 通过 readOnly 选项是只读的,我可以选择一些内容并将其拖动到其他编辑器,从而将其从源编辑器中删除
我在这里发现了3个问题:
我设法解决了前两个问题。
广告。1.
要在跨编辑器拖放过程中插入联系人,就像从联系人列表中插入联系人一样,您需要contact在数据传输对象上设置数据dataTransfer.getData( 'contact' );。不幸的是,您拖动的小部件不会将联系人存储为对象。最简单的方法是将字符串化的联系人存储为附加属性:
<span class="h-card" data-contact=\'' + JSON.stringify( contact ) + '\'>...</span>
Run Code Online (Sandbox Code Playgroud)
广告。2.
事实上,CKEditor 阻止小部件在编辑器之间拖放。为了解决这个问题,您可以创建一个drop侦听器,该侦听器将在默认侦听器(优先级 2)之前调用,并将放置类型从小部件更改为联系人,因此它将以与从编辑器下面的列表中拖动的联系人相同的方式进行处理。
// Create a drop listener which change the object from the widget to the contact.
editor.on( 'drop', function( evt ) {
var dataTransfer = evt.data.dataTransfer,
sourceEditor = dataTransfer.sourceEditor;
id = dataTransfer.getData( 'cke/widget-id' );
// If it was a widget from another editor...
if( sourceEditor && typeof id == "number" ) {
// ...get contact info from the data attribute...
var contact = sourceEditor.widgets.instances[ id ].element.data( 'contact' );
contact = JSON.parse( contact );
// ...set the contact info...
dataTransfer.setData( 'contact', contact );
// ...and remove the information that it was a widget.
dataTransfer.setData( 'cke/widget-id', null );
}
}, null, null, 2 );
Run Code Online (Sandbox Code Playgroud)
广告。3.
我无法阻止 CKEditor 表单删除拖动的元素而不阻止放置。删除是通过以下代码完成的: https: //github.com/ckeditor/ckeditor-dev/blob/06362a8715809f23d439986a122b87a37eef2e13/plugins/clipboard/plugin.js#L1409,并且不准备被阻止。我的另一个想法是防止这种拖放并触发单独的放置事件,但不幸的是我没有放置位置。您可以更改剪贴板插件以防止删除源元素并添加如下内容:
if( dataTransfer.getData( 'doNotRemoveSource' )
dataTransfer.sourceEditor.editable().extractHtmlFromRange( dragRange );
Run Code Online (Sandbox Code Playgroud)
但我不保证它会正常工作,它可能需要在小部件系统中进行更多更改,该系统也监听 drop 事件。
整个解决方案是一个 hack,完美的解决方案需要对剪贴板插件进行更深入的更改。
您可以在这里找到我的解决方案:http://codepen.io/pjasiun/pen/aNLWWM
| 归档时间: |
|
| 查看次数: |
3573 次 |
| 最近记录: |