Я пытаюсь реализовать значок, который при нажатии сохранит переменную в буфер обмена пользователя. В настоящее время я пробовал несколько библиотек, и ни одна из них не смогла это сделать.

Как правильно скопировать переменную в буфер обмена пользователя в Angular 5?

189
anonymous-dev 5 Мар 2018 в 05:40

8 ответов

Лучший ответ

Решение 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 . Пользовательская директива

Если вы предпочитаете использовать пользовательскую директиву, проверьте ответ Дана Дохотару, который представляет собой элегантное решение, реализованное с использованием ClipboardEvent.

202
Sangram Nandkhile 3 Окт 2019 в 01:24

Я думаю, что это гораздо более чистое решение при копировании текста:

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

А затем просто вызовите copyToClipboard для события click в html. ( Нажмите ) = " CopyToClipboard ( ' texttocopy ') "

45
jockeisorby 12 Окт 2018 в 08:54

Я знаю, что за это уже проголосовали здесь, но я бы предпочел использовать собственный подход директивы и полагаться на ClipboardEvent, как предложил @jockeisorby, и при этом убедиться, что слушатель корректно удален (должна быть предусмотрена та же функция). как для добавления, так и для удаления слушателей событий)

Stackblitz demo

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

65
Dan Dohotaru 23 Окт 2018 в 15:38

Модифицированная версия ответа 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);
}
12
John 16 Июл 2019 в 18:16

Начиная с Angular Material v9, теперь у него есть CDK в буфер обмена.

Буфер обмена | Угловой материал

Это может быть использовано так же просто, как

<button [cdkCopyToClipboard]="This goes to Clipboard">Copy this</button>
8
Nabel 10 Май 2020 в 14:01

Ниже метод может быть использован для копирования сообщения: -

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);
}
1
Durgesh Pal 19 Сен 2019 в 16:52

Лучший способ сделать это в 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
Rahul Basu 8 Ноя 2019 в 19:24

Первое предложенное решение работает, нам просто нужно изменить

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);
  }
0
Shreeketh K 5 Мар 2020 в 09:58