Angular 5-クリップボードにコピー


124

クリックすると変数をユーザーのクリップボードに保存するアイコンを実装しようとしています。私は現在いくつかのライブラリを試しましたが、どれもできませんでした。

Angular 5で変数をユーザーのクリップボードに正しくコピーするにはどうすればよいですか?


ngxyz-c2cを使用できます。これを行う方法は複数あります。
Ankit Singh

Angular Materialを使用している場合、バージョン9.0.0(2020年2月6日リリース)では、超使いやすいクリップボードパッケージが導入されました。Angularのドキュメントと@Nabelの回答をご覧ください。
ジョージホーキンス

回答:


235

解決策1:テキストをコピーする

HTML

<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>

.tsファイル

copyMessage(val: string){
    const selBox = document.createElement('textarea');
    selBox.style.position = 'fixed';
    selBox.style.left = '0';
    selBox.style.top = '0';
    selBox.style.opacity = '0';
    selBox.value = val;
    document.body.appendChild(selBox);
    selBox.focus();
    selBox.select();
    document.execCommand('copy');
    document.body.removeChild(selBox);
  }

解決策2: TextBoxからコピーする

HTML

 <input type="text" value="User input Text to copy" #userinput>
      <button (click)="copyInputMessage(userinput)" value="click to copy" >Copy from Textbox</button>

.tsファイル

    /* To copy Text from Textbox */
  copyInputMessage(inputElement){
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

デモはこちら


解決策3:サードパーティのディレクティブngx-clipboardをインポートする

<button class="btn btn-default" type="button" ngxClipboard [cbContent]="Text to be copied">copy</button>

解決策4:カスタムディレクティブ

カスタムディレクティブを使用する場合は、を使用して実装されたエレガントなソリューションであるDan Dohotaruの回答を確認してくださいClipboardEvent


1
素晴らしいアイデアですが、私はあなたの2番目のソリューションをコピーしCannot read property 'select' of undefined、angular 6 を使い続けました。これはangular6互換ですか?
18

1
@slevin私はそれが角度バージョンに何らかの方法で関連しているとは思いません。入力に ​​`#userinput`を追加しましたか?
Sangram Nandkhile

1
@SangramNandkhile私は何度もチェックしましたが、それでも同じエラーが発生しました。これは私のコードです。<input *ngIf="invitation_code" type="text" readonly value="{{invitation_code}}" #userinput > <button *ngIf="code_success" (click)="copyInputMessage(userinput)" value="click to copy" > Copy code </button>ありがとう
slevin

あなたも削除することができpositionlefttop、とopacity。そしてそれをaに置き換えますselBox.style.height = '0';
Mendy

マイナーな問題、constを使用しないでください
Stephen DuMont 2018

70

私はこれがすでにここで非常に投票されていることを知っていますが、カスタムディレクティブアプローチを採用して、@ jockeisorbyが示唆するようにClipboardEventに依存すると同時に、リスナーが正しく削除されていることを確認します(同じ関数を提供する必要があります)追加と削除の両方のイベントリスナー)

Stackblitz デモ

import { Directive, Input, Output, EventEmitter, HostListener } from "@angular/core";

@Directive({ selector: '[copy-clipboard]' })
export class CopyClipboardDirective {

  @Input("copy-clipboard")
  public payload: string;

  @Output("copied")
  public copied: EventEmitter<string> = new EventEmitter<string>();

  @HostListener("click", ["$event"])
  public onClick(event: MouseEvent): void {

    event.preventDefault();
    if (!this.payload)
      return;

    let listener = (e: ClipboardEvent) => {
      let clipboard = e.clipboardData || window["clipboardData"];
      clipboard.setData("text", this.payload.toString());
      e.preventDefault();

      this.copied.emit(this.payload);
    };

    document.addEventListener("copy", listener, false)
    document.execCommand("copy");
    document.removeEventListener("copy", listener, false);
  }
}

そしてそれをそのまま使う

<a role="button" [copy-clipboard]="'some stuff'" (copied)="notify($event)">
  <i class="fa fa-clipboard"></i>
  Copy
</a>

public notify(payload: string) {
   // Might want to notify the user that something has been pushed to the clipboard
   console.info(`'${payload}' has been copied to clipboard`);
}

注:window["clipboardData"]IEでは理解できないため、e.clipboardData


3
これを再利用可能なディレクティブにする功績。いい案!
Rod

1
確かに、バージョン12.xの何かから始めて、Safariには再び問題があります:)
Dan Dohotaru

2
最小限の回避策は、範囲を作成してその範囲を選択に追加することです。実際の解決策は次のようになります。stackblitz.com/ edit / angular
Dan Dohotaru

IEでwindow ["clipboardData"]が定義されていませんか?何か案が ?
ビクタージョズウィキ

モバイルでは機能しません。代わりにngx-clipboardプラグインを使用しました
the-catalin

48

テキストをコピーする場合、これはよりクリーンなソリューションだと思います:

copyToClipboard(item) {
    document.addEventListener('copy', (e: ClipboardEvent) => {
      e.clipboardData.setData('text/plain', (item));
      e.preventDefault();
      document.removeEventListener('copy', null);
    });
    document.execCommand('copy');
  }

そして、HTMLのクリックイベントでcopyToClipboardを呼び出すだけです。(クリック)= "copyToClipboard( 'texttocopy')"


2
e.clipboardDataが定義されていないため、IEでは機能しません。
Dan Dohotaru 2018年

9
しかものremoveListenerは、どちらかの引数として渡される、元のリスナーのニーズとしては動作しません
ダンDohotaru

2
削除イベントリスナーを機能させる方法については、こちらをご覧ください:stackoverflow.com/a/51843984/3849445
user123959

Angular 6では問題なく動作します!Chromeでテスト済み。ありがとうございました。
moreirapontocom

16

Angular Material v9以降、クリップボードCDKが追加されました

クリップボード| 角材

簡単に使用できます

<button [cdkCopyToClipboard]="This goes to Clipboard">Copy this</button>

それは魅力のように働きます。適切な解決策がそこにあることを決して知らなかった!
Abdullah Feroz

1
Angular Material v9から利用できます。
andreivictor

14

イベントハンドラーが適切に削除されない問題を修正するjockeisorbyの回答の修正バージョン。

copyToClipboard(item): void {
    let listener = (e: ClipboardEvent) => {
        e.clipboardData.setData('text/plain', (item));
        e.preventDefault();
    };

    document.addEventListener('copy', listener);
    document.execCommand('copy');
    document.removeEventListener('copy', listener);
}

1
Firefoxでは動作しません。エラー-– document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler
OPTIMUS


1

以下の方法は、メッセージをコピーするために使用できます:-

export function copyTextAreaToClipBoard(message: string) {
  const cleanText = message.replace(/<\/?[^>]+(>|$)/g, '');
  const x = document.createElement('TEXTAREA') as HTMLTextAreaElement;
  x.value = cleanText;
  document.body.appendChild(x);
  x.select();
  document.execCommand('copy');
  document.body.removeChild(x);
}

これは確かに良い解決策です。私のアプリケーションで試してみましたが、うまくいきました。ありがとう。
jaihind

1

Angularでこれを行い、コードをシンプルに保つための最良の方法は、このプロジェクトを使用することです。

https://www.npmjs.com/package/ngx-clipboard

    <fa-icon icon="copy" ngbTooltip="Copy to Clipboard" aria-hidden="true" 
    ngxClipboard [cbContent]="target value here" 
    (cbOnSuccess)="copied($event)"></fa-icon>

1

角度付きCDKを使用してコピーし、

Module.ts

import {ClipboardModule} from '@angular/cdk/clipboard';

プログラムで文字列をコピーする:MyComponent.ts、

class MyComponent {
  constructor(private clipboard: Clipboard) {}

  copyHeroName() {
    this.clipboard.copy('Alphonso');
  }
}

HTML経由でコピーする要素をクリックします。

<button [cdkCopyToClipboard]="longText" [cdkCopyToClipboardAttempts]="2">Copy text</button>

リファレンス:https : //material.angular.io/cdk/clipboard/overview


0

最初に提案されたソリューションは機能し、変更する必要があるだけです

selBox.value = val;

selBox.innerText = val;

つまり、

HTML:

<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>

.tsファイル:

copyMessage(val: string){
    const selBox = document.createElement('textarea');
    selBox.style.position = 'fixed';
    selBox.style.left = '0';
    selBox.style.top = '0';
    selBox.style.opacity = '0';
    selBox.innerText = val;
    document.body.appendChild(selBox);
    selBox.focus();
    selBox.select();
    document.execCommand('copy');
    document.body.removeChild(selBox);
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.