Angular 5 - Sao chép vào khay nhớ tạm


124

Tôi đang cố gắng triển khai một biểu tượng mà khi được nhấp vào sẽ lưu một biến vào khay nhớ tạm của người dùng. Tôi hiện đã thử một số thư viện và không có thư viện nào có thể làm như vậy.

Làm cách nào để sao chép đúng một biến vào khay nhớ tạm của người dùng trong Angular 5?


bạn có thể sử dụng ngxyz-c2c , có nhiều cách để làm điều đó.
Ankit Singh

Nếu bạn đang sử dụng Angular Material thì phiên bản 9.0.0 (phát hành ngày 6 tháng 2 năm 2020) đã giới thiệu gói khay nhớ tạm siêu dễ sử dụng . Xem tài liệu Angular và câu trả lời của @ Nabel .
George Hawkins

Câu trả lời:


236

Giải pháp 1: Sao chép bất kỳ văn bản nào

HTML

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

tệp .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);
  }

Giải pháp 2: Sao chép từ TextBox

HTML

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

tệp .ts

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

Demo tại đây


Giải pháp 3: Nhập ngx-clipboard chỉ thị của bên thứ 3

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

Giải pháp 4: Chỉ thị tùy chỉnh

Nếu bạn thích sử dụng chỉ thị tùy chỉnh, hãy xem câu trả lời của Dan Dohotaru, đây là một giải pháp thanh lịch được triển khai bằng cách sử dụng ClipboardEvent.


1
Ý tưởng tuyệt vời, nhưng tôi đã Cannot read property 'select' of undefinedsao chép giải pháp thứ 2 của bạn và tôi tiếp tục nhận được góc 6. Điều này có tương thích với góc 6 không?
slvin

1
@slevin Tôi không nghĩ rằng nó liên quan đến phiên bản góc cạnh theo bất kỳ cách nào. Bạn có muốn thêm `# userinput` vào đầu vào của mình không?
Sangram Nandkhile,

1
@SangramNandkhile Mình đã kiểm tra lại nhiều lần nhưng vẫn bị lỗi như vậy. Đây là mã của tôi. <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>Cảm ơn
slvin 09/07/18

Bạn thậm chí có thể loại bỏ các position, left, top, và opacity. và thay thế bằng mộtselBox.style.height = '0';
Mendy

vấn đề nhỏ, nên sử dụng const không cho
Stephen DuMont

70

Tôi biết điều này đã được bình chọn cao ở đây cho đến nay, nhưng tôi muốn sử dụng phương pháp tiếp cận chỉ thị tùy chỉnh và dựa vào ClipboardEvent như @jockeisorby đã đề xuất, đồng thời đảm bảo trình nghe được xóa chính xác (cần cung cấp cùng một chức năng cho cả trình nghe sự kiện thêm và xóa)

bản demo 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);
  }
}

và sau đó sử dụng nó như vậy

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

Lưu ý: lưu ý điều window["clipboardData"]cần thiết cho IE vì nó không hiểue.clipboardData


3
Kudo vì đã biến chỉ thị này thành chỉ thị có thể tái sử dụng. Ý tưởng tuyệt vời!
Rod

1
thực sự, bắt đầu với phiên bản 12.x một cái gì đó, Safari một lần nữa là có vấn đề :)
Dan Dohotaru

2
một workaround tối thiểu sẽ là để tạo ra một phạm vi và thêm phạm vi đó để lựa chọn, một giải pháp làm việc sẽ trông như thế này stackblitz.com/edit/angular-labs-copy-clipboard-r1
Dan Dohotaru

window ["clipboardData"] không được xác định cho tôi trong IE? Bất kỳ ý tưởng ?
Victor Jozwicki

nó không hoạt động trên thiết bị di động, tôi đã sử dụng plugin ngx-clipboard để thay thế
the-catalin

49

Tôi nghĩ rằng đây là một giải pháp gọn gàng hơn nhiều khi sao chép văn bản:

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

Và sau đó chỉ cần gọi copyToClipboard vào sự kiện nhấp chuột trong html. (click) = "copyToClipboard ('texttocopy')"


2
không hoạt động trên IE do e.clipboardData không được định nghĩa.
Dan Dohotaru

9
hơn nữa các removelistener không hoạt động hoặc như nhu cầu nghe ban đầu được thông qua như một cuộc tranh cãi
Dan Dohotaru

2
Nhìn vào đây để làm thế nào để có được làm việc loại bỏ sự kiện nghe: stackoverflow.com/a/51843984/3849445
user123959

Hoạt động tốt trong Angular 6! Đã thử nghiệm trong Chrome. Cảm ơn bạn.
moreirapontocom

16

Kể từ Angular Material v9, nó hiện có một CDK clipboard

Bảng tạm | Vật liệu góc cạnh

Nó có thể được sử dụng đơn giản như

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

Nó hoạt động như một say mê. Không bao giờ biết một giải pháp thích hợp ở đó!
Abdullah Feroz

1
có sẵn từ Vật liệu góc cạnh v9.
andreivictor

14

Phiên bản sửa đổi của câu trả lời của jockeisorby để sửa lỗi trình xử lý sự kiện không được xóa đúng cách.

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
Không hoạt động trong Firefox. Lỗi -document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler
OPTIMUS

3

Bạn có thể đạt được điều này bằng cách sử dụng các mô-đun Angular:

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

1

Phương pháp dưới đây có thể được sử dụng để sao chép thông báo: -

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

Đây thực sự là một giải pháp tốt. Tôi đã thử nó cho ứng dụng của mình và nó đã hoạt động. Cảm ơn.
jaihind

1

Cách tốt nhất để làm điều này trong Angular và giữ cho mã đơn giản là sử dụng dự án này.

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

Sao chép bằng cdk góc,

Module.ts

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

Sao chép theo chương trình một chuỗi: MyComponent.ts,

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

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

Nhấp vào một phần tử để sao chép qua HTML:

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

Tham khảo: https://material.angular.io/cdk/clipboard/overview


0

Giải pháp được đề xuất đầu tiên hoạt động, chúng tôi chỉ cần thay đổi

selBox.value = val;

Đến

selBox.innerText = val;

I E,

HTML:

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

tệp .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);
  }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.