inputやtextareaの内容をクリップボードにコピーする実装を行う機会があったので、その際に調べたことをメモ。
サンプルコード
ボタンをクリックした時に、任意のテキストをクリップボードにコピーするようにしてみます。
<button id="btn">クリップボードにコピー</button>
クリップボードへのコピーはClipboard APIを使います。
var btn = document.getElementById('btn');
btn.addEventListener('click', function(e) {
copy_to_clipboard('ここの内容をコピーします。');
});
function copy_to_clipboard(value) {
if(navigator.clipboard) {
var copyText = value;
navigator.clipboard.writeText(copyText).then(function() {
alert('コピーしました。');
});
} else {
alert('対応していません。');
}
}
Clipboard APIでクリップボードにコピーするデモページ
これでクリップボードへのコピーが実装できましたが、この方法はIEやiOS13以下の端末など一部対応していません。
Clipboard APIの対応ブラウザはこちら
別の方法として、execCommand()を使用する方法があります。
Clipboard APIの場合はコピーするテキストを指定できましたが、execCommand()の場合はページ上で選択状態のテキストをコピーする形になるため、先ほどのデモと実装方法が少し異なります。
execCommand()を使う注意点として、execCommand()は既に廃止されており、execCommand()でのコピーに取って代わるようにClipboard APIが設計されています。
記事を作成した時点では動作しているようですが、将来的に動作しなくなる可能性が高いので、使用する場合はご注意ください。
execCommand()の例として、入力エリアにフォーカスを当てた際にクリップボードにコピーするようにしてみます。
<input type="text" class="js-copy-to-clipboard" value="https://cly7796.net/blog/"> <textarea class="js-copy-to-clipboard"> cly7796.net https://cly7796.net/blog/ </textarea>
.js-copy-to-clipboardに対してコピーの処理が適用される措定です。
クリップボードへのコピーは、setSelectionRange()でテキストを選択状態にした上で、execCommand(‘copy’)を使って行います。
var copyArea = document.querySelectorAll('.js-copy-to-clipboard');
for (var i = 0; i < copyArea.length; i++) {
copy_to_clipboard(copyArea[i]);
}
function copy_to_clipboard(target) {
target.addEventListener('focus', function(e) {
// 内容を全選択
target.setSelectionRange(0, 999999);
// クリップボードにコピー
document.execCommand('copy');
});
}
9行目のsetSelectionRange()は最初はselect()を使って全選択するようにしていたのですが、iOSの場合に上手く全選択されなかったためsetSelectionRange()を使用する形に変更しました。
これでフォーカスを当てた際にクリップボードにコピーされるようになりました。
execCommand()でクリップボードにコピーするデモページ
iOSでも対応する場合の補足として、iOSでコピーしたい場合は以下のような条件があるようです。
- inputとtextareaからのみコピーが可能
- form内にない場合はcontenteditable属性がtrueである必要がある
- readonly属性がtrueの場合はコピーできない
- コピーするテキストが選択されている状態である
参考記事はこちらで、各項目を全て確認はできていないですが、手持ちのiOS12の端末でform外のinput要素でcontenteditable属性がfalseの場合でもコピーできるようだったので、バージョンによって変わっている可能性がありそうです。
先ほどのデモでは入力エリアのテキストを全選択した上でコピーしていましたが、Clipboard APIの時のようにボタンをクリックした時に指定したテキストをコピーできるようにしてみます。
<button id="btn">クリップボードにコピー</button>
仕組み上ページ内にあるテキストが選択されている必要があるので、コピー用の仮のtextareaをコピー時のみ追加する形で実装してみます。
var btn = document.getElementById('btn');
btn.addEventListener('click', function(e) {
copy_to_clipboard('ここの内容をコピーします。');
});
function copy_to_clipboard(value) {
// コピー用のtextareaを生成
var textarea = document.createElement('textarea');
textarea.style.position ='absolute';
textarea.style.opacity = 0;
textarea.style.pointerEvents = 'none';
textarea.value = value;
// 一時的にtextareaをページに追加して、コピー後に削除
document.body.appendChild(textarea);
textarea.focus();
textarea.setSelectionRange(0, 999999);
document.execCommand('copy');
textarea.parentNode.removeChild(textarea);
}
IEだとコピー時にアラートが表示されて一時的に処理が止まり、textareaが見えてしまうため、9~11行目のstyleで見えないようにしています。
execCommand()でクリップボードにコピーするデモページ2
これでexecCommand()を使ったコピーもできるようになったので、最初のClipboard APIのデモでClipboard APIに対応していなかった場合にexecCommand()を使う形にしてみます。
var btn = document.getElementById('btn');
btn.addEventListener('click', function(e) {
copy_to_clipboard('ここの内容をコピーします。');
});
function copy_to_clipboard(value) {
if(navigator.clipboard) {
var copyText = value;
navigator.clipboard.writeText(copyText).then(function() {
alert('コピーしました。');
});
} else {
copy_to_clipboard_for_old_browser(value);
}
}
function copy_to_clipboard_for_old_browser(value) {
// コピー用のtextareaを生成
var textarea = document.createElement('textarea');
textarea.style.position ='absolute';
textarea.style.opacity = 0;
textarea.style.pointerEvents = 'none';
textarea.value = value;
// 一時的にtextareaをページに追加して、コピー後に削除
document.body.appendChild(textarea);
textarea.focus();
textarea.setSelectionRange(0, 999999);
document.execCommand('copy');
textarea.parentNode.removeChild(textarea);
}
これでClipboard APIに対応していない場合はexecCommand()を使ってコピーするようになりました。
Clipboard APIとexecCommand()を使ったデモページ

コメントが承認されるまで時間がかかります。