10
14

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 5 years have passed since last update.

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

Posted at

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

前置き

今までは

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

とコピーしたい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

参考

10
14
0

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
10
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?