199 votes

Angular 5 - Copier dans le presse-papiers

Je suis en train d'essayer d'implémenter une icône qui, une fois cliquée, enregistrera une variable dans le presse-papiers de l'utilisateur. J'ai actuellement essayé plusieurs bibliothèques et aucune d'entre elles n'a été capable de le faire.

Comment puis-je copier correctement une variable dans le presse-papiers de l'utilisateur en Angular 5?

0 votes

Vous pouvez utiliser ngxyz-c2c, il existe plusieurs façons de le faire.

1 votes

Si vous utilisez Angular Material, alors la version 9.0.0 (publiée le 6 février 2020) a introduit le package de presse-papiers super facile à utiliser clipboard. Consultez la documentation d'Angular et la réponse de @Nabel sur Stack Overflow.

344voto

Sangram Points 2183

Solution 1: Copiez n'importe quel texte

HTML

Copier cela

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

Solution 2: Copiez à partir d'une zone de texte

HTML

      Copier depuis la zone de texte

Fichier .ts

    /* Pour copier du texte depuis la zone de texte */
  copyInputMessage(inputElement){
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

Démo ici


Solution 3: Importez une directive tierce ngx-clipboard

copier

Solution 4: Directive personnalisée

Si vous préférez utiliser une directive personnalisée, consultez la réponse de Dan Dohotaru qui est une solution élégante implémentée en utilisant ClipboardEvent.


Solution 5: Angular Material

Les utilisateurs d'Angular Material 9+ peuvent utiliser la fonction de copie intégrée pour copier du texte. Il existe quelques autres personnalisation disponibles telles que limiter le nombre de tentatives pour copier des données.

1 votes

Super idée, mais j'ai copié ta 2e solution et je continue d'obtenir Impossible de lire la propriété 'select' de undefined dans angular 6. Est-ce compatible avec angular6 ?

1 votes

@slevin Je ne pense pas que ce soit lié à la version d'Angular de quelque manière que ce soit. Avez-vous ajouté ` #userinput` à votre input ?

2 votes

@SangramNandkhile J'ai vérifié encore et encore, mais toujours la même erreur. Voici mon code Copier le code Merci

95voto

Dan Dohotaru Points 1155

Je sais que cela a déjà été largement voté ici à présent, mais je préfère adopter une approche de directive personnalisée et me fier à l'événement ClipboardEvent comme @jockeisorby l'a suggéré, tout en veillant à ce que l'écouteur soit correctement supprimé (la même fonction doit être fournie pour les événements d'ajout et de suppression)

stackblitz démonstration

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 = new EventEmitter();

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

et ensuite l'utiliser de la sorte

  Copier

public notify(payload: string) {
   // Vous voudrez peut-être informer l'utilisateur qu'un élément a été copié dans le presse-papiers
   console.info(`'${payload}' a été copié dans le presse-papiers`);
}

Note : remarquez que window["clipboardData"] est nécessaire pour IE car il ne comprend pas e.clipboardData

4 votes

Félicitations pour avoir fait de ceci une directive réutilisable. Super idée!

2 votes

En effet, à partir de la version 12.x, Safari pose à nouveau problème :)

3 votes

Une solution minimale de contournement consisterait à créer une plage et à ajouter cette plage à la sélection, une solution fonctionnelle ressemblerait à ceci stackblitz.com/edit/angular-labs-copy-clipboard-r1

72voto

jockeisorby Points 409

Je pense que c'est une solution beaucoup plus propre lors de la copie du texte :

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

Et ensuite il suffit d'appeler copyToClipboard sur l'événement de clic en html. (click)="copyToClipboard('texttocopy')".

2 votes

Ne fonctionne pas sur IE en raison du fait que e.clipboardData n'est pas défini.

11 votes

De plus, le removelistener ne fonctionne pas non plus car le listener d'origine doit être passé en tant qu'argument

2 votes

Regardez ici comment faire fonctionner l'événement removeEventListener : stackoverflow.com/a/51843984/3849445

20voto

John Points 166

Version modifiée de la réponse de jockeisorby qui corrige le problème du gestionnaire d'événements qui n'est pas correctement supprimé.

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 votes

Ne fonctionne pas dans Firefox. Erreur - document.execCommand(‘cut’/‘copy’) a été refusée car elle n'a pas été appelée à partir d'un gestionnaire d'événements d'utilisateur généré rapidement à l'intérieur

1voto

Durgesh Pal Points 3

La méthode ci-dessous peut être utilisée pour copier le message:-

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

0 votes

Cela est en effet une bonne solution. Je l'ai essayée pour mon application et elle a fonctionné. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X