Angular 4 - Копирование текста в буфер обмена

У меня есть значок на странице. Нажав на этот значок, я хотел бы создать текст и скопировать его в буфер обмена

<td><img src='./assets/Copy.gif' (click)="copyToClipboard()"  /></td> 

и в компоненте

  copyToClipboard() {
     this.textToCopy = this.text1 + this.text2 + this.text3;  
     this.toastr.info('Copied to Clipboard');
  }

Я посмотрел https://www.npmjs.com/package/ngx-clipboard. Однако этот пакет требует обращения к входному элементу и копирования текста из этого элемента ввода. В моем примере использования текст должен быть динамически создан, а затем добавлен в буфер обмена.

Могу ли я использовать ngx-clipboard для копирования в буфер обмена или есть другой пакет, который позволил бы мне достичь этого?

Ответ 1

Вы должны использовать директиву ngxClipboard с вашим изображением. Вот как вы должны использовать его для решения вашей проблемы:

<td>
    <img src='./assets/Copy.gif' (click)="copyToClipboard()" ngxClipboard [cbContent]="textToCopy" />
</td> 

Не забудьте добавить ClipboardModule в свой модуль приложения. Пример кода ниже:

import { ClipboardModule } from 'ngx-clipboard';

@NgModule({
  imports: [
    // Other Imports
    ClipboardModule
  ],
  // Other code
})
export class AppModule { }

Ответ 2

Взаимодействие с пользователем является обязательным для выполнения document.execCommand, который используется для копирования текста в буфер обмена.

Смотрите мой другой ответ.

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

function copyTextToClipboard(text) {
  var txtArea = document.createElement("textarea");
  txtArea.id = 'txt';
  txtArea.style.position = 'fixed';
  txtArea.style.top = '0';
  txtArea.style.left = '0';
  txtArea.style.opacity = '0';
  txtArea.value = text;
  document.body.appendChild(txtArea);
  txtArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
    if (successful) {
      return true;
    }
  } catch (err) {
    console.log('Oops, unable to copy');
  } finally {
    document.body.removeChild(txtArea);
  }
  return false;
}

Измените функцию copyToClipboard, как показано ниже, чтобы вызвать функцию copyTextToClipboard

copyToClipboard() {
    this.textToCopy = this.text1 + this.text2 + this.text3;
    var result = this.copyTextToClipboard(this.textToCopy);
    if (result) {
        this.toastr.info('Copied to Clipboard');
    }
}

Ответ 3

Это самый простой способ скопировать в буфер обмена.

В вашем шаблоне

<button (click)="copyToClipboard(sharableLink)">Copy link</button>
<input type="text" value="This is the value to copy" #sharableLink>

В компоненте

copyToClipboard(element) {
    element.select();
    document.execCommand('copy');
    this.toaster('success', 'Success!', 'Link copied to clipboard.');
  }

Ответ 4

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

В вашем шаблоне

<a class="accent" (click)="copyLink(textToCopy)">{{textToCopy}}</a>

И в твоем компоненте

copyLink(text:string) {
        const event = (e: ClipboardEvent) => {
            e.clipboardData.setData('text/plain', text);
            e.preventDefault();
            // ...('copy', e), as event is outside scope
            document.removeEventListener('copy', e);
        }
        document.addEventListener('copy', event);
        document.execCommand('copy');
    }

Ответ 5

ngx-clipboard теперь не требует использования элемента ввода. Теперь это более прямо и предоставить несколько способов сделать это. Один из способов сделать это - просто использовать ClipboardService. Из трех, документация

import { ClipboardService } from 'ngx-clipboard'

constructor(private _clipboardService: ClipboardService){
...
}
copy(text: string){
  this._clipboardService.copyFromContent(text)
}

Но в моем случае это не сработало. И я получил несколько предупреждений во время компиляции, что зависимости от пиров не встречаются. Так как я использовал Angular 4, эти предупреждения я ожидал. Но есть простой способ сделать это с @ViewChild, если вышеуказанное решение не работает для вас.

в вашем HTML:

<textarea name="copyText" #copyText id="" style="opacity: 0;height: 0;"></textarea>

И в компоненте:

@ViewChild('copyText', { read: ElementRef }) copyText: ElementRef;

copyText() {
    const element = this.copyText.nativeElement;
    element.value = 'some text';
    element.focus();
    element.select();
    document.execCommand('copy');
}

Это простой ванильный JavaScript-подход с Angular @ViewChild.

Ответ 6

Проблема (позже подчеркнутая OP) утвержденного ответа с использованием NgxClipboard заключается в том, что содержимое не может быть установлено динамически.

Использование прослушивателя событий (щелчка) не работает, поскольку он запускается после выполнения ngxClipboard.

Итак, просто определите [cbContent] с помощью получателя @Input и забудьте о событии (click):

В шаблоне:

<button ngxClipboard [cbContent]="foo">Click me</button>

В компоненте:

@Input()
get foo() {
    // Dynamic generation of the text to put in the clipboard:
    return this.text1 + this.text2 + this.text3
}