contenteditable div にテキストを貼り付けたいのですが、テキストエリアとして反応します。
テキストエリアに貼り付けるのと同じようにフォーマットを維持したいことに注意してください(ワード、エクセルなどから)。
そう。
1) contenteditable div にテキストを貼り付ける
2) クリップボードからテキストを取得する
3) 値をクリップボードからテキストエリアにプッシュする (方法がわからない??)
4) テキストエリアから値を取得し、contenteditable div に配置
する?
3 に答える
私は CKEditor のコア開発者で、偶然にも過去 4 か月間、クリップボードのサポートと関連する作業を行っていました :) 残念ながら、貼り付けの処理方法全体を説明することはできません。自分でimplを書いた後でも、私にとってはトリッキーです:D
ただし、次のヒントを参考にしてください。
wysiwyg エディターを作成しないでください。既存のものを使用してください。それはあなたのすべての時間を消費するでしょう、それでもあなたのエディターはバグだらけです. 私たちと他の 2 人の主要な編集者 (なぜ 3 人しか存在しないのかを推測します) は、何年にもわたってこれに取り組んでおり、まだ完全なバグ リストがあります ;)。
独自のエディターを本当に作成する必要がある場合は、http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/clipboard/plugin.js を確認してください。これは、書き直す前の古い impl ですが、動作します可能な限りどこでも。コードは恐ろしいです...しかし、それはあなたを助けるかもしれません.
1 つのイベントだけですべてのブラウザーを処理することはできません
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 では両方の貼り付けイベントをリッスンし、残りの IE では
paste
. IE でいくつかのイベントを防止する必要があります。これは、両方をリッスンしているため、処理が 2 倍になる場合があるためです。これは私が推測する最も難しい部分です。テキストエリアに貼り付けるのと同じようにフォーマットを維持したいことに注意してください(ワード、エクセルなどから)。
フォーマットのどの部分を保持しますか? Textarea は、基本的なもの (ブロックの書式設定) のみを保持します。
http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js#L120の 123 行目までを参照してください。これはタスクの最後の部分であり、コンテンツを選択範囲に挿入します。
現在のソリューションは 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>
私は選択を保存して復元するために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);
}