18

ユーザーが画像を に貼り付けられるようにしようとしていdivます。問題は、Firefox で動作する必要があることです。

私が読んだことによると、バージョン 13 以降の Firefox (私が思うに) はクリップボードへの JavaScript アクセスを許可しておらず、クリップボードにevent.clipboardは存在しません。Gmail や Yahoo では Firefox でも許可されているので、できることはわかっています。

jQuery、JavaScript、HTML5 など、可能な限り動作するようにしたいだけです。最新の Firefox で動作する限り問題ありません。(ただし、フラッシュはありません)。

4

1 に答える 1

14

この質問のコードをクロスブラウザー ペーストの実装に使用しました。テストしたすべてのブラウザーで動作します (実際のソリューション/コードを下にスクロールします)。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 で機能します。

于 2013-03-08T22:50:37.683 に答える