typescript - Angular 5 - Kopiera till urklipp


Jag försöker implementera en ikon som, när den klickas på, kommer att spara en variabel till användarens urklipp. Jag har för närvarande försökt med flera bibliotek och inget av dem har kunnat göra det.

Hur kopierar jag korrekt en variabel till användarens urklipp i Angular 5?

Svar #1

Lösning 1: Kopiera vilken text som helst

HTML

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

.ts-fil

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);
  }

Lösning 2: Kopiera från en 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-fil

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

Demo här


Lösning 3: Importera en tredjepartsdirektiv ngx-clipboard

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

Lösning 4: Anpassad direktiv

Om du föredrar att använda en egen direktiv, kolla Dan Dohotarus svar som är en elegant lösning implementerad med ClipboardEvent.


Lösning 5: Angular Material

Angular Material 9 + användare kan använda den inbyggda urklippsfunktionen för att kopiera text. Det finns några fler anpassningsalternativ tillgängliga, såsom att begränsa antalet försök att kopiera data.

Svar #2

Jag vet att detta redan har röstats högt här vid det här laget, men jag skulle hellre gå för en anpassad direktivlösning och förlita mig på ClipboardEvent som @jockeisorby föreslog, samtidigt som jag säkerställer att lyssnaren tas bort korrekt (samma funktion måste anges för både tillägg och borttagning av event listeners)

stackblitz-demonstration

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);
  }
}

och sedan använda det som sådant

<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`);
}

Obs: notera att window["clipboardData"] behövs för IE eftersom det inte förstår e.clipboardData

Svar #3

Jag tycker att detta är en mycket renare lösning när man kopierar text:

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

Och sedan bara kalla copyToClipboard vid klickhändelsen i HTML. (click)="copyToClipboard('texttocopy')".

Svar #4

Från och med Angular Material v9 har det nu en clipboard CDK

Urklipp | Angular Material

Den kan användas lika enkelt som

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

Svar #5

Kopiera med Angular CDK,

Modul.ts

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

Kopiera en sträng programmässigt: MyComponent.ts,

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

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

Klicka på ett element för att kopiera via HTML:

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

Referens: https://material.angular.io/cdk/clipboard/overview

Svar #6

Modifierad version av jockeisorbys svar som åtgärdar att evenemangshanteraren inte tas bort korrekt.

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);
}

Svar #7

Du kan uppnå detta med hjälp av Angular-moduler:

navigator.clipboard.writeText('your text').then().catch(e => console.error(e));

Svar #8

Det är enkelt, bror

i .html-fil

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

i .ts-fil

copyMessage(text: string) {
  navigator.clipboard.writeText(text).then().catch(e => console.log(e));
}

Relaterade artiklar