6

我想将文本粘贴到内容可编辑的 div 中,但作为文本区域做出反应。
请注意,我想保留格式,因为我会将其粘贴到我的文本区域(来自 word、excel ...)。
所以。
1)将文本粘贴到 contenteditable div
2)我从剪贴板获取文本
3)我将我的值从剪贴板推送到我的 textarea,(不知道如何??)
4)从我的 textarea 获取值并将其放在我的 contenteditable div

任何建议?

4

3 回答 3

19

我是 CKEditor 的核心开发人员,巧合的是,在过去的 4 个月里,我一直在从事剪贴板支持和相关工作 :) 不幸的是,我无法向您描述如何处理粘贴的整个方式,因为 impl 的故事太即使我自己写了 impl 对我来说也很棘手:D

但是,这里有一些提示可能会对您有所帮助:

  1. 不要编写所见即所得的编辑器——使用现有的编辑器。它会消耗你所有的时间,你的编辑器仍然会出错。我们和其他人......两个主要编辑(猜猜为什么只有三个存在)多年来一直在努力,我们仍然有完整的错误列表;)。

  2. 如果您真的需要编写自己的编辑器,请查看http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/clipboard/plugin.js - 这是旧的 impl,在我重写之前,但它有效任何可能的地方。代码很糟糕......但它可能会对你有所帮助。

  3. 您不可能仅通过一个事件来处理所有浏览器paste。为了处理所有粘贴方式,我们同时使用 -beforepastepaste.

  4. 您需要处理许多(大量:D)浏览器的怪癖。我无法向您描述它们,因为即使几周后我也不记得所有这些了。但是,我们文档中的一小段摘录可能对您有用:

    粘贴命令(由非本地粘贴使用 - 例如从我们的工具栏中)

    * fire 'paste' on editable ('beforepaste' for IE)
    * !canceled && execCommand 'paste'
    * !success && fire 'pasteDialog' on editor
    

    从本机上下文菜单和菜单栏中粘贴

    (Fx & Webkits are handled in 'paste' default listner.
    Opera cannot be handled at all because it doesn't fire any events
    Special treatment is needed for IE, for which is this part of doc)
    * listen 'onpaste'
    * cancel native event
    * fire 'beforePaste' on editor
    * !canceled && getClipboardDataByPastebin
    * execIECommand( 'paste' ) -> this fires another 'paste' event, so cancel it
    * fire 'paste' on editor
    * !canceled && fire 'afterPaste' on editor
    

    其余的技巧 - 在 IE 上,我们监听两个粘贴事件,其余的仅监听paste. 我们需要阻止 IE 上的一些事件,因为我们同时监听两者,有时这可能会导致双重处理。这是我猜最棘手的部分。

  5. 请注意,我想保留格式,因为我会将其粘贴到我的文本区域(来自 word、excel ...)。

    您想保留格式的哪些部分?Textarea 将只保留基本的 - 块格式。

  6. 请参阅http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js#L120直到第 123 行 - 这是任务的最后一部分 - 将内容插入选择。

于 2012-07-02T08:24:12.680 回答
1

当前的解决方案在 IE/SAF/FF 中完美运行但我仍然需要修复“非”键盘事件,当通过鼠标单击粘贴时......键盘“粘贴”事件的当前解决方案:

$(document).ready(function() {
    bind_paste_textarea();      
});


function bind_paste_textarea(){
    var activeOnPaste = null;
    $("#mypastediv").keydown(function(e){
        var code = e.which || e.keyCode;
        if((code == 86)){
            activeOnPaste = $(this);
            $("#mytextarea").val("").focus();
        }
    });
    $("#mytextarea").keyup(function(){
        if(activeOnPaste != null){
            $(activeOnPaste).focus();
            activeOnPaste = null;
        }
    });
}

<h2>DIV</h2>
<div id="mypastediv" contenteditable="true" style="width: 400px; height: 400px; border: 1px solid orange;">

</div>
<h2>TEXTAREA</h2>
<textarea id="mytextarea" style="width: 400px; height: 400px; border: 1px solid red;"></textarea>
于 2012-06-28T09:08:17.563 回答
0

我已经使用rangy 库来保存和恢复选择来实现这一点。

我还在相同的函数中使用库执行了一些其他工作,我已经从这个示例中删除了这些工作,因此这不是最佳代码。

HTML

<div><div id="editor"contenteditable="true" type="text"></div><div>

Javascript

var inputArea = $element.find('#editor');
var debounceInterval = 200;

function highlightExcessCharacters() {
    // Bookmark selection so we can restore it later
    var sel = rangy.getSelection();
    var savedSel = sel.saveCharacterRanges(editor);

    // Strip HTML
    // Prevent images etc being pasted into textbox
    inputArea.text(inputArea[0].innerText);

    // Restore the selection
    sel.restoreCharacterRanges(editor, savedSel);
}

// Event to handle checking of text changes
var handleEditorChangeEvent = (function () {

    var timer;

    // Function to run after timer passed
    function debouncer() {
        if (timer) {
            timer = null;
        }
        highlightExcessCharacters();
    }

    return function () {
        if (timer) {
            $timeout.cancel(timer);
        }
        // Pass the text area we want monitored for exess characters into debouncer here
        timer = $timeout(debouncer, debounceInterval);
    };
})();

function listen(target, eventName, listener) {
    if (target.addEventListener) {
        target.addEventListener(eventName, listener, false);
    } else if (target.attachEvent) {
        target.attachEvent("on" + eventName, listener);
    }
}

// Start up library which allows saving of text selections
// This is useful for when you are doing anything that might destroy the original selection
rangy.init();
var editor = inputArea[0];

// Set up debounced event handlers
var editEvents = ["input", "keydown", "keypress", "keyup", "cut", "copy", "paste"];
for (var i = 0, eventName; eventName = editEvents[i++];) {
    listen(editor, eventName, handleEditorChangeEvent);
}
于 2015-06-29T17:00:48.320 回答