Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@khsk

任意の文字列をコピーするテクニック

そろそろ決定版が欲しいな。

前置き

今までは

と既存のものを選択してコピーするか、無いものをコピーしたいときは

とコピーしたいDOMを作ってそれを選択するというまどろっこしい方法を取っていた。

Qiitaにも色々記事はある。

でもこれらの方法は主にRangeの処理がとてもとても面倒なので、最近は使っていない。

目新しい内容ではないが、使用頻度が高いのでまとめる。

要件

  • 任意のJS側で用意した文字列をクリップボードに保存させる。
  • 動作のトリガーは主にボタンクリックのイベント駆動
  • 通常のコピー動作を阻害しない
  • 複数のコピー処理を追加したときに互いに干渉しない
  • 後処理が楽であって欲しい

コード

好きなイベントに好きなコピーイベントを設置するjs

// 登録したい要素
const element = document.createElement('hoge'); // document.querySelector('hoge')
element.addEventListener('click', (e) => {
  document.addEventListener('copy', (e) => {
    e.preventDefault();
    e.clipboardData.setData('text/plain', 'コピーしたい文字列');
  }, {once:true});
  document.execCommand('copy');
});

これだけ。
何かのイベントを契機にcopyイベントを登録して、document.execCommand('copy');で即座に手動実行。
clipboardData.setData()で選択中文字列ではなく色々手動で設定できる。
もちろんコールバック中にDOM操作ができるので、欲しい文字列はDOM中から自由に取ってきて加工できる。

イベントにonceオプションをつけることで、実行後にイベント登録は解除される。
よってコピー後も通常のコピーが出来るし、別のcopyイベントも登録できるし、当然再度同じイベントを登録することもできる。
後腐れなし、と思っている。

(オマケ)Bootstrapなどがあるときの視覚的補助

自分で作っているならば動作に不安は無いが、知らぬ人にはコピーが起きても変化が無いので味気ない。


// ツールチップの遅延非表示。クリックで表示を前提にしている(delayオプションが効かないのでやむなく)
const hideTooltipDelay = (element, dilay) => {
  setTimeout(() => {
    // ツールチップはBootstrap(jQuery)の機能なので、Qiitaが読み込んでいるものを使う
    $(element).tooltip('hide');
  }, dilay);
}

// クリックすることで指定のstringをクリップボードにコピーするElementを返す関数
const createCopyButton = (string, tag = 'span') => {
  if (typeof string == 'function') {
    string = string();
  }
  const element = document.createElement(tag);
  element.addEventListener('click', (e) => {
    document.addEventListener('copy', (e) => {
      e.preventDefault();
      e.clipboardData.setData('text/plain', string);
    }, {once:true,});
    document.execCommand('copy');
    hideTooltipDelay(e.target, 1000)
  });

  element.dataset.toggle        = 'tooltip';
  element.dataset.originalTitle = 'Copied';
  element.dataset.trigger       = 'click';
  return element;
}

褒められたコードではないのだが、ツールチップでcopyされたことを目視することができる。
が、本当に処理周りの理解が追いついてなくて、消し方や2回めのクリック時にtooltipが出ない問題を抱えている。(manual triggerで作ったほうがよかったかな)

commentcopy.gif

参考

14
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
14
Help us understand the problem. What is going on with this article?