javascriptで任意のテキストをクリップボードにコピーする

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
この三人の中では一番能力を活用する場面が多かった気もする

この記事を三行にまとめると

テキストボックスの文字をコピー
spanタグで囲われた文字をコピー
リンクの文字をコピー
文字をコピペしたい時、マウスとかでビーッとドラッグしてコピーしたい文字を選択してから右クリックなりCtrl+Cすれば選択範囲をコピーできますよね。

このコピー操作ですが、javascriptで同じ動きを実装することも可能です。実際にネットで「javascript クリップボードにコピー」とかで検索すればいくらでもやり方が見つかります。

ただ、テキストボックスやテキストエリアの文字をコピーする方法は簡単に見つかるんですが、そうじゃない文字、例えばspanタグで囲われた文字とかリンクのアンカーテキストとかをコピーする方法は意外と見つからないような気がしたので、今回はそれをやってみたいと思います。



テキストボックスの文字をコピー

と言いつつも、まずはテキストボックスの文字をコピーするやり方を見てみます。そっちの方がたぶん説明しやすいんで。

やり方は簡単です。こんな感じのコードを書けばボタンを押した時にテキストボックスの中身がコピーされます。

<input type="text" value="コピーできた?" id="text" />
<button type="button" onclick="copy()">button</button>

<script>
function copy() {
  let text = document.getElementById('text');
  text.select();
  document.execCommand('copy');
}
</script>

実際に動きを確認したい場合は以下のページにサンプルを用意しましたので、よかったら。

サンプル

やっていることとしては、ボタンを押した時に「text」というidを持つテキストボックスを取得して、その中身を選択状態にしてから「execCommand」というメソッドでコピーしています。この選択状態にするってのはマウスでドラッグした時なんかと同じ動きです。

execCommandはコンテンツに対して何らかの操作を行うメソッドでして、コピーだけじゃなくカットとかペーストとかもできます。

document.execCommand

ようは文字を選択状態にさえできればコピーができるわけです。そしてjavascriptを使えばテキストボックスじゃない文字とかも選択状態にはできる。



spanタグで囲われた文字をコピー

てなわけで今度はボタンを押したらspanタグで囲われた文字を選択状態にしてコピーされるコードを書いてみます。

<span id="span">コピーできたでしょ?</span>
<button type="button" onclick="copy()">button</button>

<script>
function copy(){
  //範囲を指定
  let range = document.createRange();
  let span = document.getElementById('span');
  range.selectNodeContents(span);

  //指定した範囲を選択状態にする
  let selection = document.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);

  //コピー
  document.execCommand('copy');
  alert('コピーしました');
}
</script>

さっきよりはちょい面倒な感じに見えますが、これでspanタグの中身を選択状態にして文字をコピーできます。サンプルで確認する場合はこちら。

サンプル

Rangeオブジェクトを使って範囲を指定し、Selectionオブジェクトを使って指定した範囲を選択状態にし、execCommandでコピーを実行しているという動きです。

RangeオブジェクトやSelectionオブジェクトが何かってーと……すまん、僕も実はよく分かってない。なので詳しく知りたい方はこの辺を見てもらえればよいかと……。

Range

Selection

Selectionオブジェクトに関しては、今回は「document.getSelection()」と書きましたが「window.getSelection()」の方がもしかしたら正式な書き方かもしれない。どっちでも動くんだけどね。もしかしたらブラウザによるのかな?

コードの中にある「selection.removeAllRanges()」というのは、選択範囲を全解除するメソッドです。一つのページにコピー対象の要素が一つしかないならこのメソッドはなくても問題ないんだけど、ないよりはあった方が良いと思います。要素が複数ある場合、コピーする前に一度選択範囲を解除しないと二つ目以降のコピーが何か上手く動かないみたいなので。何言ってるか分からんって人は実際にremoveAllRanges()なしで動かしてみれば分かるぜよ。



リンクの文字をコピー

ほんじゃあ次はリンクをクリックした時にその文字をコピーしてみましょう。やり方はspanの時と同じです。

<a href="javascript:void(0)" onclick="copy(this)">コピーできたよね?</a>

<script>
function copy(element){
  //範囲を指定
  let range = document.createRange();
  range.selectNodeContents(element);

  //指定した範囲を選択状態にする
  let selection = document.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);

  //コピー
  document.execCommand('copy');
  alert('コピーしました');
}
</script>

spanの時と全く同じコードでも動くんですが、それじゃあアレなんで、引数に自分自身を渡すようにしてみました。これなら「document.getElementById」を使わなくてもエレメントを取得できるので、ほんのちょっとだけコードが短くなります。idも省略できるね。

サンプル






ということでjavascriptを使ったテキストのコピーでした。繰り返しになりますけど、やり方はどうあれ選択状態にできればこっちのもんっちゅー話です。

モダンなブラウザなら問題なく動作すると思います。僕が自分で試した限りではChrome、Safari、Firefox、IE11あたりは正常に動作しましたが、もし動かねーって場合はブラウザのバージョンとかを確認してみてください。それか僕のコードにミスがあって動かなかったぞって場合はすまんが一言言っちくり。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください