Posted at

リストをボタンクリックでクリップボードにコピーしたい。


Introduction

ボタン一つでリストに書いている情報をクリップボードにコピーして、メモ帳とかにペーストしたくなった話。

とりあえずブレスト」というプロダクトでブレインストーミングした結果を最後に表示しているんですが、そのリストをクリップボードにコピーしてメモ帳とかメールとかにペーストしたくなったので作ってみました。

textareaの入力値をexecCommand("Copy")するとよいらしいのですが、今回は<ul>のリストとして表示しているitemをコピーしたかったのでちょっと工夫。


コピー対象


sample.html

<ul id="copy_target">

<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>

<button type="button" id="copy_button">Copy</button>

<div id="copy_area"></div>


こんな感じのHTMLをイメージしてます。copy_buttonをクリックするとクリップボードにコピーされて、メモ帳とかにペーストすると

item1

item2
item3

となることをめざします!

<div id="copy_area"></div>は今のところ何も表示されていませんが、隠し味です。


いきなり答え合わせ


sample.coffee

$("#copy_button").click ->

list = $("#copy_target li")
$("#copy_area").append('<textarea id="copy_textarea"></textarea>')
target = $("#copy_textarea")
list.each ->
target.append($(@).text() + '\n')
target.select()
document.execCommand("Copy")
target.remove()
alert("ブレスト結果をコピーしました!")

coffeescriptで書いてます。それぞれ何をしているのか説明します!


コードの中身

$("#copy_button").click ->

まず、ボタンクリックをトリガーにしてます。

list = $("copy_target li")

ここで、<ul id="copy_target"></ul>内の<li>要素たちをlistに入れてます。

$("#copy_area").append('<textarea id="copy_textarea"><textarea>')

target = $("#copy_textarea")

<div id="copy_area">内に一時的にtextareaを作りました。その要素をtargetに入れてます。

list.each ->

target.append($(@).text() + '\n')

listの中には3つの<li>要素が入っているのでeachを使って一つずつ取り出してあげます。

そして、append($(@).text()でその要素ごとの文字列を先ほど作ったtextareaの中に入力していきます。'\n'を入れることで<textarea>内で改行してあげてます。

target.select()

document.execCommand("Copy")

ここまでくれば普通のtextareaのコピーとやり方は一緒です。select()textareaに入力している文字列を全選択し、document.execCommand("Copy")でクリップボードにコピーします。

target.remove()

このままだとさっきまでなかったはずのtextareaが残ったままになってしまうので削除しちゃいます。

alert("ブレスト結果をコピーしました!")

これはあってもなくても、他のやり方でもよいと思いますが、ユーザーにコピーしたことを伝えるためにダイアログを出して完了です。


Conclusion

最初は「textareaならできるけど、リストは無理かー」みたいに簡単に諦めちゃうところだったのですが、append()を使うことでなんだってできることを知りました。今回は<ul>を使いましたが、この方法ならなんだっていけますね。


Reference