【问题标题】:Issues with drag and drop in CKEditorCKEditor 中的拖放问题
【发布时间】:2015-06-12 15:32:46
【问题描述】:

我正在编写一个使用 CKEditor 作为 HTML 编辑器的小型笔记网络应用程序。我已经能够很好地集成它,但有一个例外 - 拖放功能。它主要是有效的 - 但尽管尝试了很多不同的方法,但有两个怪癖我无法解决。

我的要求很简单——我从应用程序外部将任何文件拖到 CKEditor 中,它应该在可编辑文本中插入一个简单的锚标记,并带有指向该文件的本地链接。目前,我正在我自己的名为 filemanager 的 CKEditor 插件中实现拖放:

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>";


这确实可以正常工作,因此该功能的基本实现似乎可以正常工作。但是,这是我的两个问题:

  1. 将文件放到编辑器中但在实际文本区域之外(例如在编辑器中的最后一行文本下方)不会禁用默认行为。如何为编辑器的这个区域运行 preventDefault() ?一直在尝试各种地方的活动,但没有结果。
  2. HTML 不会插入到鼠标光标的位置,即使 CKEditor 在那里预览插入符号。相反,它插入到文档中插入符号当前所在的位置,与您放置的位置无关。这破坏了该功能的核心功能 - 有没有办法在鼠标位置插入 HTML?我会这样认为,因为 CKEditor 实际上会在鼠标所在的位置预览插入符号,但我查看了文档但没有结果。

有没有人知道如何解决上述两个问题?如果有帮助,我正在使用 nw.js,因此 webapp 将始终在 Chromium 中运行。感谢您的任何回复!

【问题讨论】:

  • 我猜你们中的很多人想做的事情(或者至少是必要的 API)都会登陆CKEditor 4.5
  • 并确保查看演示 - ckeditor.com/tmp/4.5.0-beta/image-upload.html :)。顺便提一句。在 4.5.0 之前,CKEditor 根本不涉及 DnD 行为——发生的一切都是本机行为。

标签: javascript jquery html drag-and-drop ckeditor


【解决方案1】:

我最终设法解决了这些问题。

为了防止 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();
}

然后我在 drop 事件中简单地添加了

moveSelectionToDropPosition(editor, e);

一切都按预期进行!

希望这可以帮助将来遇到类似问题的其他人:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多