grit

grit

Clipboard API:新しい非同期のコピー、貼り付けAPI

Safari ブラウザで navigator.clipboard.writeText を直接使用すると、問題なくコピーできますが、promise の後に navigator.clipboard.writeText を使用すると、権限がないエラーが発生します。具体的なエラーは次のとおりです。

Unhandled Rejection (NotAllowedError): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

原因:

  1. 開発中のコピー内容は API リクエストによって生成されるため、Safari はこの操作を拒否します。セキュリティ上の制限により、上記のメソッドはユーザーがページと対話している場合にのみ正常に機能します。コピー操作がユーザーによってトリガされない場合(タイマーや他の非対話的な方法で行われる場合など)、ブラウザの制限の影響を受ける可能性があります。
  2. document.execCommand () は同期的にクリップボードにアクセスするため、DOM の読み書きのみが可能です。

Clipbo ard API#

新しい非同期のコピー、貼り付け API。ユーザーが許可した場合、システムのクリップボードの読み取りと書き込みにアクセスできます。 Clipboard API は、切り取り、コピー、貼り付けの機能を Web アプリケーションで実装するために使用できます。writeText メソッドを呼び出すだけで、テキストを正常にコピーできます。この API は、document.execCommandを使用してクリップボードにアクセスするためのものです。

コピー:コンテンツをクリップボードに書き込む#

writeText()

テキストをシステムのクリップボードに書き込むには、writeText () を呼び出すことができます。これにより、テキストが正常にコピーされ、Ctrl+V でコピーした内容を取得できます。

async function copyText(text) {
  try {
    await navigator.clipboard.writeText(text)
    console.log('ページのコンテンツがクリップボードにコピーされました')
  } catch (e) {
    console.log(`コピーに失敗しました:${e}`)
  }
}

write()

実際には、writeText () は一般的な write () メソッドの省略形であり、画像をクリップボードにコピーすることもできます。画像が正常にコピーされた後、read () メソッドを使用して読み取る必要があります。write () メソッドは、ClipboardItem オブジェクトの配列を引数として受け取ります。新しい ClipboardItem オブジェクトを作成するには、MIME タイプをキーとして、Blob を値として指定する必要があります。

現在、複数の ClipboardItems のサポートは実装されていませんが、複数のキーと値のデータはサポートされています。

  const data = new ClipboardItem({
    // [MIME]: Blob
    'image/png': Blob,
    'text/plain': Blob
  })
  // サポートされている
  await navigator.clipboard.write([data]);
  // サポートされていない
  await navigator.clipboard.write([data, data]);

注意:Clipboard API は実験的な API であるため、Safari ブラウザでの動作が異なる場合があります。

  1. https 環境でのみデバッグ使用できます。それ以外の場合、エラーが発生します。NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
  2. ClipbordItem の blob プロパティの値は Promise を返す必要があります。
const data = new ClipboardItem({
  'text/plain': new Promise((resolve) => {
    resolve(new Blob(['example text'], { type: 'text/plain' }))
  })
})

貼り付け:クリップボードからデータを読み取る#

readText()

テキストをクリップボードから読み取るには、readText () を呼び出すことができます。

async function getClipboardText() {
  try {
    const text = await navigator.clipboard.readText();
    console.log(`貼り付け内容:${text}`);
    // いくつかの操作
  } catch (e) {
    console.error(`クリップボードからデータを取得できませんでした:${e}`);
  }
}

read()

read () は ClipboardItems オブジェクトのリストを返します。画像をクリップボードから読み取るには、ClipboardItems リストを反復処理して取得することができます。

async function getClipboardContents () {
  try {
    const clipboardItems = await navigator.clipboard.read() // clipboardItemsリスト
    for (const clipboardItem of clipboardItems) {
      // types: ClipboardItemで使用可能なMIMEタイプの配列。
      for (const type of clipboardItem.types) { 
        // リクエストされたMIMEタイプを使用して解析されたBlobを返すPromise。
        // MIMEタイプが見つからない場合はエラーが返されます。
        const blob = await clipboardItem.getType(type) 
        if (type === 'text/plain') { // テキスト
            // Blobインターフェースのtext()メソッドはPromiseを返します。
            // このPromiseは、Blobの内容を含む文字列として解析され、UTF-8として解釈されます。
            const text = await blob.text()
            console.log(text)
          } else if (type === 'image/png') { // 画像
            const url = URL.createObjectURL(blob)
            console.log(url)
          }
      }
    }
  } catch (e) {
    console.error(`貼り付けに失敗しました:${e}` )
  }
}

イベントの監視#

Clipboard API はEventTargetから継承されています(イベントを受け取り、リスナーを作成できるオブジェクトを実装する DOM インターフェース)。したがって、イベントの監視も可能です。現時点では、イベントの監視方法は見つかっていませんが、現在は以前の document.addEventListener を使用して監視することができます。

document.addEventListener('paste', async (e) => {
  e.preventDefault();
  // 複数のコンテンツまたは画像コンテンツ
  getClipboardContents()
  
  // テキストのみの場合
  if (navigator.clipboard) {
    text = await navigator.clipboard.readText();
  }
  else {
    text = e.clipboardData.getData('text/plain'); // 以前の方法
  }
});

この記事はMix Spaceから xLog に同期されました。
元のリンクはhttps://liu-wb.com/posts/default/clipboardです。


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。