ベストアンサー1
概要
クリップボードにコピーするための主なブラウザ API は 3 つあります。
非同期クリップボード API
[navigator.clipboard.writeText]
- テキスト中心の部分は以下で利用可能Chrome 66 (2018 年 3 月)
- アクセスは非同期であり、JavaScript の約束セキュリティ ユーザー プロンプト (表示される場合) がページ内の JavaScript を中断しないように記述できます。
- 変数からテキストを直接クリップボードにコピーできます。
- HTTPS 経由で提供されるページでのみサポートされます。
- Chrome 66 では、非アクティブなタブは権限プロンプトなしでクリップボードに書き込むことができます。
document.execCommand('copy')
(非推奨)��- 2015 年 4 月現在、ほとんどのブラウザがこれをサポートしています (以下のブラウザ サポートを参照)。
- アクセスは同期的です。つまり、セキュリティ プロンプトの表示やユーザーによる操作が完了するまで、ページ内の JavaScript は停止されます。
- テキストは DOM から読み取られ、クリップボードに配置されます。
- 2015 年 4 月までのテストでは、クリップボードへの書き込み中に権限プロンプトが表示されたのは Internet Explorer のみでした。
コピーイベントのオーバーライド
- クリップボードAPIドキュメントを参照コピーイベントのオーバーライド。
- 任意のコピー イベントからクリップボードに表示される内容を変更でき、プレーン テキスト以外の他の形式のデータを含めることができます。
- 質問に直接答えていないため、ここでは説明しません。
一般的な開発メモ
コンソールでコードをテストしている間は、クリップボード関連のコマンドが機能することを期待しないでください。通常、ページはアクティブである必要があります (非同期クリップボード API) または、( document.execCommand('copy')
) がクリップボードにアクセスできるようにするには、ユーザーの操作 (ユーザークリックなど) が必要です。詳細については、以下を参照してください。
重要(2020/02/20にここに記載)
この投稿は元々クロスオリジン IFRAME の権限の廃止その他IFRAME「サンドボックス」埋め込まれたデモの「コード スニペットの実行」ボタンと「codepen.io の例」が一部のブラウザー (Chrome や Microsoft Edge を含む) で動作しないようにします。
開発するには、独自の Web ページを作成し、そのページを HTTPS 接続経由で提供してテストおよび開発を行います。
コードが動作することを示すテスト/デモ ページを次に示します。https://deanmarktaylor.github.io/clipboard-test/
非同期 + フォールバック
新しい Async Clipboard API のブラウザー サポートのレベルにより、document.execCommand('copy')
ブラウザー カバレッジを良好にするには、このメソッドにフォールバックする必要があるでしょう。
以下に簡単な例を示します (このサイトに埋め込むと動作しない可能性があります。上記の「重要」の注意をお読みください)。
function fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
(codepen.io の例は動作しない可能性があります。上記の「重要」の注意をお読みください) このスニペットは Stack Overflow の埋め込みプレビューではうまく動作しないことに注意してください。ここで試すことができます:https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011
非同期クリップボード API
Chrome 66 では、権限 API を介して「権限をリクエスト」し、クリップボードへのアクセスをテストする機能があることに注意してください。
var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
document.execCommand('コピー')
この投稿の残りの部分では、API のニュアンスと詳細について説明しますdocument.execCommand('copy')
。
ブラウザのサポート
JavaScriptは
(非推奨)��document.execCommand('copy')
サポートが拡大しました。ブラウザの更新については、以下のリンクを参照してください。
- Internet Explorer 10以上(ただしこのドキュメントInternet Explorer 5.5 以降から何らかのサポートがあったことを示します。
- Google Chrome 43+ (~2015年4月)
- Mozilla Firefox 41+ (2015 年 9 月までに出荷予定)
- Opera 29+ (Chromium 42 ベース、2015 年 4 月現在)
簡単な例
(このサイトに埋め込むと動作しない可能性があります。上記の「重要」の注意をお読みください)
var copyTextareaBtn = document.querySelector('.js-textareacopybtn');
copyTextareaBtn.addEventListener('click', function(event) {
var copyTextarea = document.querySelector('.js-copytextarea');
copyTextarea.focus();
copyTextarea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
});
<p>
<button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
<textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>
複雑な例: 入力を表示せずにクリップボードにコピーする
上記の簡単な例は、画面上にtextarea
または要素が表示されている場合に最適です。input
場合によっては、input
/textarea
要素を表示せずにテキストをクリップボードにコピーしたいことがあります。これは、この問題を回避する方法の一例です (基本的には、要素を挿入し、クリップボードにコピーし、要素を削除します)。
Google Chrome 44、Firefox 42.0a1、Internet Explorer 11.0.8600.17814 でテスト済み。
(このサイトに埋め込むと動作しない可能性があります。上記の「重要」の注意をお読みください)
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if the element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in the top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of the white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
document.body.removeChild(textArea);
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
その他の注意事項
ユーザーがアクションを起こした場合にのみ機能する
すべてのdocument.execCommand('copy')
呼び出しは、クリック イベント ハンドラーなどのユーザー アクションの直接の結果として実行する必要があります。これは、ユーザーが予期しないときにクリップボードが混乱するのを防ぐための対策です。
を参照してくださいGoogle Developersの投稿はこちら詳細については。
クリップボード API
完全な Clipboard API ドラフト仕様は、次の場所にあります。クリップボード
サポートされていますか?
document.queryCommandSupported('copy')
true
コマンドがブラウザでサポートされている場合は返されます。- 今呼び出された場合に成功するかどうかを
document.queryCommandEnabled('copy')
返します。コマンドがユーザーが開始したスレッドから呼び出され、その他の要件が満たされていることを確認します。true
document.execCommand('copy')
ただし、ブラウザの互換性の問題の例として、2015 年 4 月から 10 月までの Google Chrome は、コマンドがユーザーが開始したスレッドから呼び出された場合true
にのみ戻りました。document.queryCommandSupported('copy')
互換性の詳細については下記をご覧ください。
ブラウザ互換性の詳細
ユーザーのクリックの結果として呼び出される/ブロックdocument.execCommand('copy')
でラップされた単純な呼び出しでは、最大限の互換性が得られますが、次の使用法にはいくつかの条件があります。try
catch
document.execCommand
、 、document.queryCommandSupported
の呼び出しはすべて/ブロックdocument.queryCommandEnabled
で囲む必要があります。try
catch
異なるブラウザの実装とブラウザのバージョンでは、 を返す代わりに呼び出されたときに異なるタイプの例外がスローされますfalse
。
さまざまなブラウザの実装はまだ流動的であり、クリップボード APIまだドラフト段階なので、テストを忘れずに行ってください。