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.
原因:
- 開発中のコピー内容は API リクエストによって生成されるため、Safari はこの操作を拒否します。セキュリティ上の制限により、上記のメソッドはユーザーがページと対話している場合にのみ正常に機能します。コピー操作がユーザーによってトリガされない場合(タイマーや他の非対話的な方法で行われる場合など)、ブラウザの制限の影響を受ける可能性があります。
- 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 ブラウザでの動作が異なる場合があります。
- https 環境でのみデバッグ使用できます。それ以外の場合、エラーが発生します。NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
- 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です。