クリップボード操作 クリップボード 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.typesのconst型) {
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.items の const 項目) {
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