0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

意外と複雑な、JavaScriptで「クリップボードにコピー」

Last updated at Posted at 2020-06-25

メールアドレスなどでよく見かける、「クリックしてクリップボードにコピー」
よく見かけるが故にcopy('コピーしたい文言')みたいな感じで簡単に出来ると思ったら、意外と複雑だったので備忘録です。

clipboardCopy: function(e) {
        e.preventDefault()
        const targetSentence = 'コピーしたい文言'
        let input = document.createElement('input')
        input.readOnly = true
        document.body.appendChild(input)
        input.value = targetSentence
        input.select()
        document.execCommand('copy')
        document.body.removeChild(input)
      }

ざっくりとした流れ

①inputを生成する
let input = document.createElement('input')

②body内の一番最後の要素に、①のinputノードを追加する
document.body.appendChild(input)

③inputの中に、任意のコピーしたい文字列を挿入する
input.value = targetSentence

④inputの内容をselectする
input.select()

⑤選択している内容に対して、コピーコマンドを実行する
document.execCommand('copy')

⑥inputは用済みなのでさようならする
document.body.removeChild(input)

なぜinputか

select()を使えるのがキモなんだと思います。

補足

execCommand()について

コマンドキーを押して出来ることがだいたいできるみたいです。
cutやpasteもできます。ただし、pasteはバックグラウンドのみ。
(個人情報などがクリップボードに入っていた場合勝手に抜き取られる可能性があるため。)
ちなみにIEだとpasteも許容しているみたいです。さすがですね。
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard

ん?と思ったのは、これ非推奨なんですよね。
ほかにクリップボードとやりとりできる代替え手段があるのでしょうか?また調べてみます。
https://developer.mozilla.org/ja/docs/Web/API/Document/execCommand

時間がかかったところ

iOSで確認すると、クリックと同時に勝手にスクロールされる

iOSですと、input系を選択(タップ)した時にその要素がズームされたり、中央よりちょい上の位置にスクロールされたりします。
この例では、作成したinputをbodyの中の最後の子ノードのうしろに追加しているので、ページの最後にinputが出現している形になります。

そのため、テキストリンクをタップした瞬間に、ページ下方へのスクロールが走ります。
よかれと思ってやってくれているんだろうけども、inputはユーザが認識するよりも先に消えてしまうのでなんの意味もないです…。

ここで、inputをreadonlyに設定することで、スクロールを防ぎます。
input.readOnly = true

ズームされる

こちらはjsの問題ではなく、iOSの仕様と関係しています。
iOSですと16px未満のfont-sizeをもつinputをタップすると、問答無用でズームされます。
上記の実装でも目にはinputはみえませんが、input.selectをしているので謎にズームされます。
ズーム禁止にしてしまうとユーザビリティに影響が出るので、ひとまずSPでのfont-sizeを16pxにしてことなきを得ました。
(これを知ってたら最初から16pxにしてたのに…次回から気をつけよう)

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?