我希望将文本粘贴到一个可信的div中,但作为textarea进行反应
请注意,我想保留格式,因为我会将其粘贴到我的textarea中(来自word,excel ...)
所以。
1)在可信的div中粘贴文本
2)我从剪贴板中获取文本
3)我将我的价值从剪贴板推到我的textarea,(不知道怎么做?)
4)从我的textarea获取价值并将其放在我满意的div中
有什么建议吗?
答案 0 :(得分:17)
我是CKEditor的核心开发人员,巧合过去4个月我一直致力于剪贴板支持和相关的东西:)不幸的是,我无法描述你如何处理粘贴的整个方式,因为它的故事即使在我自己写完impl之后,impl对我来说也太棘手了:D
但是,这里有一些提示可以帮到你:
不要写wysiwyg编辑器 - 使用存在的编辑器。它将消耗你所有的时间,你的编辑仍然会有错误。我们和其他人...两位主要编辑(猜测为什么只有三位存在)正在研究这个问题多年,我们仍然有完整的错误列表;)。
如果你真的需要编写自己的编辑器,请查看http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/clipboard/plugin.js - 这是旧的impl,在我重写之前,但它可以在任何可能的地方工作。代码很糟糕......但它可能对你有帮助。
您只能通过一个事件paste
来处理所有浏览器。为了处理所有粘贴方式,我们同时使用了beforepaste
和paste
。
您需要处理的浏览器怪癖的数量(数量巨大: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上的某些事件,因为因为我们有时会监听这两个事件,所以这可能导致双重处理。这是我猜中最棘手的部分。
请注意,我想保留格式,因为我会将其粘贴到我的textarea中(来自word,excel ...)。
您希望保留哪些格式? Textarea将只保留基本格式 - 块格式化。
请参阅http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js#L120直到第123行 - 这是任务的最后一部分 - 将内容插入到选择中。
答案 1 :(得分: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>
答案 2 :(得分:0)
我已使用rangy library来保存和恢复选择。
我还在相同的函数中使用库执行了一些其他的工作,我已经从这个例子中删除了,所以这不是最佳代码。
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);
}