[JavaScript] テキストエリアの文章をクリップボードにコピーしたい
- コンテンツの内容をコピペして利用してもらう場合に、コピペ用のボタンを設置すると使いやすいページになります
- また、ボタンにイベントトラッキングなどの計測の仕組みを入れることで、そのコンテンツがユーザーの役に立つものだったか(コピペに値するものだったか)を推測する材料としても役立てることができます
- jQueryを使った実装例はこちら
サンプルコード
html
<textarea></textarea>
<button class="copy_clipboard">クリップボードにコピー</button>
JavaScript
document.addEventListener('DOMContentLoaded', function() {
function copyClipboard(event) {
const clipboard = document.createElement('textarea');
clipboard.value = event.target.previousElementSibling.value;
event.target.appendChild(clipboard);
clipboard.select();
document.execCommand('copy');
event.target.removeChild(clipboard);
}
const buttons = document.getElementsByClassName('copy_clipboard');
for(let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', copyClipboard);
}
});
サンプルコードの解説
const clipboard = document.createElement('textarea');
- まず、仮のテキストエリアを生成します
- 一旦ここにコピー対象となるテキストエリアの内容を写し、仮テキストエリアの内容をクリップボードにコピーします
- 一見すると回りくどい処理に見えますが、クリップボードへのコピーを行う「document.execCommand('copy');」処理は、コピー対象となるテキストエリアが選択状になっている必要があります
- テキストエリアを選択状態にするとテキストエリアの見た目が変わってしまう(枠に色がつく、テキストが反転するなど)ため、コピペ用の仮テキストエリアを用意しています
- また、textarea以外の「選択状態」という概念がない要素からコピーを行う場合も想定してこのような作りにしています
clipboard.value = event.target.previousElementSibling.value;
- 「copyClipboard」関数の引数「event」には、クリックという操作イベントに関する情報がセットされており、「event.target」には、クリックイベントを発生させたボタンの情報がセットされています
- 「event.target.previousElementSibling」でボタン要素の一つ前の要素であるテキストエリアを特定し、その値を取得しています
- 押したボタンの一つ前の要素からコピーするようにすることで、同じページに複数のコピペボタンを配置してもそれぞれのテキストエリアからコピーできるようにしています
event.target.appendChild(clipboard);
clipboard.select();
document.execCommand('copy');
event.target.removeChild(clipboard);
- 生成した仮テキストエリアをhtml要素として登録します。表示とは無関係の要素なので、ボタンに対して「appendChild」します
- 仮テキストエリアを選択状態にし、「document.execCommand('copy');」でコピーを実行します
- コピー後は忘れずに生成した仮テキストエリアを削除します
const buttons = document.getElementsByClassName('copy_clipboard');
for(let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', copyClipboard);
}
- コピー処理を行う「copyClipboard」関数をボタンに登録します
- 「copy_clipboard」というクラスが設定された各ボタンのクリックイベントに関数を登録しています
textarea以外の要素からコピーする場合
html
<code>ソースコード</code>
<button class="copy_clipboard">クリップボードにコピー</button>
JavaScript
document.addEventListener('DOMContentLoaded', function() {
function copyClipboard(event) {
const clipboard = document.createElement('textarea');
clipboard.value = event.target.previousElementSibling.innerHTML;
event.target.appendChild(clipboard);
clipboard.select();
document.execCommand('copy');
event.target.removeChild(clipboard);
}
const buttons = document.getElementsByClassName('copy_clipboard');
for(let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', copyClipboard);
}
});
- 変更点は一箇所だけです。要素から文字列をコピーするときの処理を「event.target.previousElementSibling.value;」から「event.target.previousElementSibling.innerHTML;」にしています
ご質問など受け付けています
記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。
ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。