クリップボード操作 クリップボード API チュートリアル

導入

ブラウザでは、JavaScript スクリプトでクリップボードの読み書きを行うことができ、コンテンツを自動的にコピーまたは貼り付けできます。

一般に、スクリプトはユーザーの期待を満たさない方法でユーザーのクリップボードを変更すべきではありません。ただし、「ワンクリック コピー」機能など、ユーザーがボタンをクリックすると、指定したコンテンツが自動的にクリップボードに入力されるなど、これが非常に便利になる場合があります。

現在、クリップボード操作を実装するには 3 つの方法があります。

  • Document.execCommand() メソッド
  • 非同期クリップボード API
  • copyイベントとpasteイベント

この記事では、これら 3 つの方法を 1 つずつ紹介します。

Document.execCommand() メソッド

Document.execCommand() はクリップボードを操作する従来の方法であり、さまざまなブラウザでサポートされています。

コピー、切り取り、貼り付けの 3 つの操作をサポートします。

  • document.execCommand('copy') (コピー)
  • document.execCommand('cut') (カット)
  • document.execCommand('paste') (貼り付け)

(1) コピー操作

コピーするときは、最初にテキストを選択してから document.execCommand('copy') を呼び出すと、選択したテキストがクリップボードに入力されます。

const inputElement = document.querySelector('#input');
inputElement.select();
document.execCommand('コピー');

上記の例では、スクリプトはまず入力ボックス inputElement (inputElement.select()) 内のテキストを選択し、次に document.execCommand('copy') がそれをクリップボードにコピーします。

コピー操作はイベント リスニング関数に配置し、ユーザーによってトリガーされる (たとえば、ユーザーがボタンをクリックする) のが最適であることに注意してください。スクリプトが自律的に実行される場合、一部のブラウザーはエラーを報告する可能性があります。

(2) ペースト操作

貼り付けるときに document.execCommand('paste') を呼び出すと、クリップボードの内容が現在フォーカスされている要素に出力されます。

const pastelText = document.querySelector('#output');
ペーストテキスト.focus();
document.execCommand('貼り付け');

(3) デメリット

Document.execCommand() メソッドは便利ですが、いくつかの欠点があります。

まず、選択したコンテンツをクリップボードにコピーすることしかできませんが、任意のコンテンツをクリップボードに書き込むことはできません。

次に、これは同期操作であるため、大量のデータをコピー/ペーストするとページがフリーズします。一部のブラウザでは、ユーザーに許可を求めるプロンプト ボックスが表示され、ユーザーが選択する前にページが応答しなくなります。

これらの問題を解決するために、ブラウザ メーカーは非同期クリップボード API を提案しました。

非同期クリップボード API

クリップボード API は、従来の document.execCommand() メソッドよりも強力かつ合理的な、次世代のクリップボード操作メソッドです。

すべての操作は非同期であり、ページラグを引き起こすことなく Promise オブジェクトを返します。さらに、任意のコンテンツ (写真など) をクリップボードに入れることができます。

navigator.clipboard プロパティは、すべての操作が実行される Clipboard オブジェクトを返します。

const ClipboardObj = navigator.clipboard;

「navigator.clipboard」プロパティが「未定義」を返した場合、現在のブラウザがこの API をサポートしていないことを意味します。

ユーザーが機密データ (パスワードなど) をクリップボードに保存する可能性があるため、スクリプトによる任意の読み取りを許可するとセキュリティ リスクが生じるため、この API には多くのセキュリティ制限があります。

まず、Chrome ブラウザでは、HTTPS プロトコルを使用するページのみがこの API を使用できると規定されています。ただし、開発環境 (「localhost」) では、暗号化されていないプロトコルの使用が許可されています。

次に、呼び出し時にユーザーの許可を明示的に取得する必要があります。アクセス許可の具体的な実装では、Permissions API を使用します。クリップボードに関連する 2 つのアクセス許可: clipboard-write (書き込みアクセス許可) と clipboard-read (読み取りアクセス許可) です。 「書き込み権限」はスクリプトに自動的に付与されますが、「読み取り権限」はユーザーが明示的に付与する必要があります。つまり、クリップボードに書き込む場合、スクリプトは自動的に完了しますが、クリップボードを読み取る場合、ブラウザは、読み取りに同意するかどうかをユーザーに尋ねるダイアログ ボックスをポップアップ表示します。

さらに、スクリプトは常に現在のページのクリップボードを読み取ることに注意してください。これによってもたらされる問題の 1 つは、関連するコードを開発者ツールに貼り付けて直接実行すると、エラーが報告される可能性があることです。これは、この時点の現在のページは Web ページではなく開発者ツールのウィンドウであるためです。

(async () => {
  const text = await navigator.clipboard.readText();
  コンソール.ログ(テキスト);
})();

上記のコードを開発者ツールに貼り付けて実行すると、エラーが報告されます。コードの実行中は開発者ツール ウィンドウが現在のページであり、このページにはクリップボード API が依存する DOM インターフェイスがないためです。解決策の 1 つは、関連するコードを setTimeout() に入れて実行を遅らせ、関数を呼び出す前にブラウザのページ ウィンドウを素早くクリックして現在のページに変更することです。

setTimeout(async () => {
  const text = await navigator.clipboard.readText();
  コンソール.ログ(テキスト);
}、2000);

上記のコードを開発者ツールに貼り付けて実行した後、Web ページのページ ウィンドウをすぐにクリックして現在のページにし、エラーが報告されないようにします。

クリップボード オブジェクト

Clipboard オブジェクトには、クリップボードの読み取りと書き込みのための 4 つのメソッドが用意されています。これらはすべて非同期メソッドであり、Promise オブジェクトを返します。

Clipboard.readText()

Clipboard.readText() メソッドは、クリップボード内のテキスト データをコピーするために使用されます。

document.body.addEventListener(
  'クリック'、
  非同期 (e) => {
    const text = navigator.clipboard.readText(); を待ちます。
    コンソール.ログ(テキスト);
  }
)

上の例では、ユーザーがページをクリックすると、クリップボード内のテキストが出力されます。ブラウザは、クリップボードを読み取るスクリプトに同意するかどうかをユーザーに尋ねるダイアログ ボックスをポップアップ表示することに注意してください。

ユーザーが同意しない場合、スクリプトはエラーを報告します。現時点では、try...catch 構造体を使用してエラーを処理できます。

非同期関数 getClipboardContents() {
  試す {
    const text = navigator.clipboard.readText(); を待ちます。
    console.log('貼り付けられた内容: ', text);
  } キャッチ (エラー) {
    console.error('クリップボードの内容を読み取ることができませんでした: '、エラー);
  }
}

クリップボード.read()

Clipboard.read() メソッドは、テキスト データまたはバイナリ データ (画像など) のデータをクリップボードにコピーするために使用されます。この方法にはユーザーからの明示的な許可が必要です。

このメソッドは Promise オブジェクトを返します。オブジェクトの状態が解決されると、配列を取得できます。各配列メンバーは ClipboardItem オブジェクトのインスタンスです。

非同期関数 getClipboardContents() {
  試す {
    const ClipboardItems = navigator.clipboard.read(); を待ちます。
    for (const ClipboardItem of ClipboardItems) {
      for (clipboardItem.typesconst型) {
        const blob = await ClipboardItem.getType(type);
        console.log(URL.createObjectURL(blob));
      }
    }
  } キャッチ (エラー) {
    console.error(err.name, err.message);
  }
}

ClipboardItem オブジェクトは、単一のクリッピング項目を表します。各クリッピング項目には、ClipboardItem.types プロパティと ClipboardItem.getType() メソッドがあります。

ClipboardItem.types プロパティは配列を返します。そのメンバーはクリッピング アイテムに使用できる MIME タイプです。たとえば、クリッピング アイテムは HTML 形式またはプレーン テキスト形式で貼り付けることができ、2 つの MIME タイプ ( ) を持ちます。 text/html および text/plain)。

ClipboardItem.getType(type) メソッドは、クリップボード項目のデータを読み取り、Promise オブジェクトを返すために使用されます。このメソッドは、クリッピング項目の MIME タイプをパラメータとして受け入れ、このタイプのデータを返します。このパラメータは必須です。そうでない場合は、エラーが報告されます。

Clipboard.writeText()

Clipboard.writeText() メソッドは、テキスト コンテンツをクリップボードに書き込むために使用されます。

document.body.addEventListener(
  'クリック'、
  非同期 (e) => {
    await navigator.clipboard.writeText('Yo')
  }
)

上記の例では、ユーザーが Web ページをクリックした後、スクリプトがテキスト データをクリップボードに書き込みます。

このメソッドにはユーザーの許可は必要ありませんが、エラーを防ぐために try...catch に置くことをお勧めします。

非同期関数 copyPageUrl() {
  試す {
    navigator.clipboard.writeText(location.href); を待ちます。
    console.log('ページの URL がクリップボードにコピーされました');
  } キャッチ (エラー) {
    console.error('コピーに失敗しました: '、エラー);
  }
}

Clipboard.write()

Clipboard.write() メソッドは、テキスト データまたはバイナリ データの任意のデータをクリップボードに書き込むために使用されます。

このメソッドは、クリップボードに書き込まれるデータを表す ClipboardItem インスタンスをパラメータとして受け取ります。

試す {
  const imgURL = 'https://dummyimage.com/300.png';
  const data = await fetch(imgURL);
  const blob = await data.blob();
  navigator.clipboard.write([
    new ClipboardItem({
      [blob.type]: blob
    })
  ]);
  console.log('イメージがコピーされました。');
} キャッチ (エラー) {
  console.error(err.name, err.message);
}

上の例では、スクリプトは画像をクリップボードに書き込みます。 Chrome ブラウザは現在、PNG 形式での画像の書き込みのみをサポートしていることに注意してください。

ClipboardItem() はブラウザーによってネイティブに提供されるコンストラクターであり、ClipboardItem インスタンスを生成するために使用されます。オブジェクトのキー名はデータの MIME タイプ、およびキー値です。データそのものです。

次の例は、同じクリッピング項目の値を複数の形式でクリップボードに書き込みます。1 つはテキスト データで、もう 1 つはバイナリ データであり、さまざまな状況で貼り付けることができます。

関数コピー() {
  const image = await fetch('kitten.png');
  const text = new Blob(['かわいい寝ている子猫'], {type: 'text/plain'});
  const item = new ClipboardItem({
    'text/plain': テキスト、
    '画像/png': 画像
  });
  await navigator.clipboard.write([項目]);
}

コピーイベント、カットイベント

ユーザーがデータをクリップボードに入れると、「copy」イベントがトリガーされます。

次の例では、ユーザーがクリップボードに入力したテキストを大文字に変換します。

const ソース = document.querySelector('.source');

source.addEventListener('コピー', (イベント) => {
  const 選択 = document.getSelection();
  event.clipboardData.setData('text/plain',selection.toString().toUpperCase());
  イベント.preventDefault();
});

上の例では、イベント オブジェクトの clipboardData プロパティにクリップボード データが含まれています。これは、次のプロパティとメソッドを持つオブジェクトです。

  • Event.clipboardData.setData(type, data): クリップボード データを変更するには、データ タイプを指定する必要があります。
  • Event.clipboardData.getData(type): クリップボードデータを取得するには、データ型を指定する必要があります。
  • Event.clipboardData.clearData([type]): クリップボード データをクリアします。データ タイプを指定できます。タイプを指定しない場合、すべてのタイプのデータがクリアされます。
  • Event.clipboardData.items: すべてのクリップボード項目を含む配列のようなオブジェクトですが、通常はクリップボード項目は 1 つだけです。

次の例では、ユーザーのコピー操作をインターセプトし、指定されたコンテンツをクリップボードに置きます。

const クリップボードアイテム = [];

document.addEventListener('copy', async (e) => {
  e.preventDefault();
  試す {
    クリップボード項目 = []; にします。
    for (e.clipboardData.itemsconst 項目) {
      if (!item.type.startsWith('image/')) {
        続く;
      }
      クリップボードアイテム.push(
        new ClipboardItem({
          [item.type]: アイテム、
        })
      );
      navigator.clipboard.write(clipboardItems); を待ちます。
      console.log('イメージがコピーされました。');
    }
  } キャッチ (エラー) {
    console.error(err.name, err.message);
  }
});

上記の例では、e.preventDefault() を使用してクリップボードのデフォルト操作をキャンセルし、スクリプトがコピー操作を引き継ぎます。

cut イベントは、ユーザーが切り取り操作を実行するとトリガーされ、その処理は copy イベントとまったく同じであり、切り取りデータも Event.clipboardData プロパティから取得されます。

イベントを貼り付け

ユーザーがクリップボード データを使用して貼り付け操作を実行すると、「paste」イベントがトリガーされます。

次の例では、貼り付け操作をインターセプトし、スクリプトを使用してクリップボードからデータを取得します。

document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const text = navigator.clipboard.readText(); を待ちます。
  console.log('貼り付けられたテキスト: ', text);
});

参考リンク


作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0