この質問のコードをクロスブラウザー ペーストの実装に使用しました。テストしたすべてのブラウザーで動作します (実際のソリューション/コードを下にスクロールします)。event.clipboardData
は、貼り付けイベントの実行が完了するとすぐに期限切れになることに注意してください。
私は先に進み、これが Firefox バージョン 19 で動作することを 4 倍に確認しました (13 は利用できませんが、この質問は新しいバージョンでの機能の低下に関するものだったようです)。
以下は、から引用した回答ですNico Burns
。
解決
IE6+、FF 3.5+、Opera、Chrome、Safari の最近のバージョンでテスト済み。
function handlepaste (elem, e) {
var savedcontent = elem.innerHTML;
if (e && e.clipboardData && e.clipboardData.getData) {// Webkit - get data from clipboard, put into editdiv, cleanup, then cancel event
if (/text\/html/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/html');
}
else if (/text\/plain/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/plain');
}
else {
elem.innerHTML = "";
}
waitforpastedata(elem, savedcontent);
if (e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup
elem.innerHTML = "";
waitforpastedata(elem, savedcontent);
return true;
}
}
function waitforpastedata (elem, savedcontent) {
if (elem.childNodes && elem.childNodes.length > 0) {
processpaste(elem, savedcontent);
}
else {
that = {
e: elem,
s: savedcontent
}
that.callself = function () {
waitforpastedata(that.e, that.s)
}
setTimeout(that.callself,20);
}
}
function processpaste (elem, savedcontent) {
pasteddata = elem.innerHTML;
//^^Alternatively loop through dom (elem.childNodes or elem.getElementsByTagName) here
elem.innerHTML = savedcontent;
// Do whatever with gathered data;
alert(pasteddata);
}
<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
説明
onpaste
イベントにはhandlepaste
関数が関連付けられており、2 つの引数 (つまり、イベントが関連付けられている要素への参照) とイベント オブジェクトが渡されthis
ますevent
。
handlepaste
機能:
最初の行は、編集可能な div の内容を変数に保存するだけなので、最後に再度復元できます。
if
ブラウザが Webkit ブラウザ (chrome または safari) であるかどうかをチェックし、そうである場合は、編集可能な div の内容を貼り付けられるデータに設定します。次に、イベントをキャンセルして、Webkit が何かを 2 回貼り付けるのを防ぎます。これは、webkit が扱いにくく、単に div をクリアすると何も貼り付けられないためです。
Webkit ブラウザーでない場合は、編集可能な div をクリアするだけです。
waitforpastedata
次に、関数を呼び出します
waitforpastedata
機能:
貼り付けたデータはすぐには表示されないため、これが必要です。そのため、すぐに呼び出した場合processpaste
、処理するデータがありません。
編集可能な div にコンテンツがあるかどうかを確認し、コンテンツがある場合は を呼び出しますprocesspaste
。そうでない場合は、タイマーを設定して自分自身を呼び出し、20 ミリ秒で再度確認します。
processpaste
機能:
この関数は、編集可能な div (現在は貼り付けられたデータ) の innerHTML を変数に保存し、編集可能な div の innerHTML を元の値に復元し、貼り付けられたデータをアラートします。明らかに、実際の使用シナリオでは、アラート データ以外の何かが必要になる可能性があります。ここから、好きなことを行うことができます。
おそらく、貼り付けたデータに何らかのデータ サニタイズ プロセスを実行することも必要になるでしょう。これは、編集可能な div 内にある間、または抽出された文字列に対して行うことができます。
実際の状況では、おそらく前に選択を保存し、後で復元することをお勧めします (カーソル位置を contentEditable <div> に設定します)。次に、ユーザーが貼り付け操作を開始したときにカーソルがあった位置に、貼り付けられたデータを挿入できます。
PS このコード、IE <= 8 およびjsfiddleの組み合わせは機能しないようですが、非 jsfiddle 環境では ie <= 8 で機能します。