我正在编写一个使用CKEditor作为HTML编辑器的小型webetapp。我已经能够很好地集成它,只有一个例外 - 拖放功能。它主要起作用 - 但是尽管尝试了很多不同的方法,但我仍然能够解决两个怪癖。
我的要求很简单 - 我从应用程序外部将任何文件拖到CKEditor中,它应该在可编辑文本中插入一个简单的锚标记,并带有指向该文件的本地链接。目前,我正在我自己的CKEditor插件中实现拖放操作,名为filemanager:
CKEDITOR.plugins.add( 'filemanager', {
init: function( editor ) {
editor.on('contentDom', function(contentDom) {
//Runs upon dropping a file into the editor
contentDom.editor.document.on('drop', function(e) {
//prevents default behavior as long as it's an actual file drag and drop (if it's dragging text etc. inside the editor, keep default behavior)
if(e.data.$.dataTransfer.files.length)
{
e.data.preventDefault();
}
//Goes through all the dropped files and insert HTML with links
for (var i = 0; i < e.data.$.dataTransfer.files.length; ++i) {
CopyData(e.data.$.dataTransfer.files[i].path);
}
});
});
//Creates the link in the editor
function CopyData(path, range)
{
//Link HTML
var fileHTML;
/* Code to parse the path into HTML to be inserted */
editor.insertHtml(fileHTML);
}
}
});
我省略了大部分CopyData函数,因为格式不相关,但它会生成一个div,例如:
fileHTML = "<a href=\""+path+"\" class=\"fileLink\" target=\"_blank\">"+fileName+"</a>";
这确实很好用,所以该功能的基本实现似乎有效。但是,这是我的两个问题:
有没有人有关于如何解决上述两个问题的想法?如果它有帮助,我使用的是nw.js,因此webapp将始终在Chromium中运行。感谢任何回复!
答案 0 :(得分:0)
我最终设法解决了这些问题。
为了防止DOM元素之外的默认行为,我将此代码添加到我的CKEditor插件中:
var iframeWin = window.document.getElementsByTagName('iframe')[0].contentWindow;
iframeWin.addEventListener("dragover",function(e){
e = e || iframeWin.event;
if(e.dataTransfer.files.length)
{
e.preventDefault();
}
},false);
iframeWin.addEventListener("drop",function(e){
e = e || iframeWin.event;
if(e.dataTransfer.files.length)
{
e.preventDefault();
}
},false);
这正确地识别了我需要禁用默认行为的iframe .if(e.dataTransfer.files.lenght)条件确保这仅适用于拖入应用程序的文件,而不是在编辑器中拖动内容。
在鼠标光标处插入HTML比较棘手!这不能归功于我 - 我发现一个函数在CKEditor错误跟踪器上完成大部分工作,并编辑它以在这种情况下工作:
function moveSelectionToDropPosition( editor, dropEvt )
{
var $evt = dropEvt.data.$,
$range,
range = editor.createRange();
// Make testing possible.
if ( dropEvt.data.testRange ) {
dropEvt.data.testRange.select();
return;
}
// Webkits.
if ( document.caretRangeFromPoint ) {
$range = editor.document.$.caretRangeFromPoint( $evt.clientX, $evt.clientY );
range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset );
range.collapse( true );
}
// FF.
else if ( $evt.rangeParent ) {
range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset );
range.collapse( true );
}
// IEs.
else if ( document.body.createTextRange ) {
$range = editor.document.getBody().$.createTextRange();
$range.moveToPoint( $evt.clientX, $evt.clientY );
var id = 'cke-temp-' + ( new Date() ).getTime();
$range.pasteHTML( '<span id="' + id + '">\u200b</span>' );
var span = editor.document.getById( id );
range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START );
span.remove();
}
range.select();
}
在掉落事件中,我只需添加
moveSelectionToDropPosition(editor, e);
这一切都按预期工作了!
希望这可能有助于将来遇到类似问题的其他人:)