Angular 5 - 复制到剪贴板

问题描述 投票:0回答:17

我正在尝试实现一个图标,单击该图标会将变量保存到用户的剪贴板。我目前已经尝试了几个库,但没有一个能够这样做。

如何在 Angular 5 中将变量正确复制到用户的剪贴板?

angular typescript angular5
17个回答
359
投票

解决方案 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: 从文本框复制

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: 自定义指令

如果您更喜欢使用自定义指令,请查看 Dan Dohotaru 的 answer,这是一个使用

ClipboardEvent
实现的优雅解决方案。


解决方案 5: Angular Material

Angular Material 9+ 用户可以利用内置剪贴板功能来复制文本。还有一些可用的自定义设置,例如限制尝试复制数据的次数。


98
投票

我知道这已经在这里得到了高度投票,但我宁愿采用自定义指令方法并按照@jockeisorby 的建议依赖 ClipboardEvent,同时确保正确删除侦听器(需要相同的功能为添加和删除事件侦听器提供)

堆栈闪电战演示

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


75
投票

我认为这是复制文本时更简洁的解决方案:

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

然后只需在 html 中的点击事件上调用

copyToClipboard
(click)="copyToClipboard('texttocopy')"
.


39
投票

从 Angular Material v9 开始,它现在有一个剪贴板 CDK

剪贴板 |角材料

它可以像

一样简单地使用
<button [cdkCopyToClipboard]="This goes to Clipboard">Copy this</button>

25
投票

使用angular cdk复制,

模块.ts

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

以编程方式复制一个字符串:MyComponent.ts,

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

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

单击要通过 HTML 复制的元素:

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

参考: https://material.angular.io/cdk/clipboard/overview


20
投票

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

15
投票

您可以使用 Angular 模块实现此目的:

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

4
投票

对我来说

document.execCommand('copy')
给出了deprecated警告,我需要复制的数据在
<div>
里面作为textNode而不是
<input>
<textarea>

这就是我在 Angular 7 中的做法(灵感来自@Anantharaman 和@Codemaker 的回答):

<div id="myDiv"> &lt &nbsp This is the text to copy. &nbsp &gt </div>
<button (click)="copyToClipboard()" class="copy-btn"></button>
 copyToClipboard() {
    const content = (document.getElementById('myDiv') as HTMLElement).innerText;
    navigator['clipboard'].writeText(content).then().catch(e => console.error(e));

  }
}

绝对不是最好的方法,但它达到了目的。


3
投票

这很简单兄弟

在 .html 文件中

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

在 .ts 文件中

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

2
投票
// for copy the text
import { Clipboard } from "@angular/cdk/clipboard"; // first import this in .ts
 constructor(
    public clipboard: Clipboard
  ) { }   
 <button class="btn btn-success btn-block"(click) = "onCopy('some text')" > Copy< /button>

 onCopy(value) {
     this.clipboard.copy(value);
    }


 // for paste the copied text on button click :here is code
    
    <button class="btn btn-success btn-block"(click) = "onpaste()" > Paste < /button>
    
    onpaste() {
      navigator['clipboard'].readText().then(clipText => {
        console.log(clipText);
      });
    }

1
投票

以下方法可用于复制消息:-

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
投票

在 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>

0
投票

第一个建议的解决方案有效,我们只需要改变

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
投票

使用纯 Angular 和 ViewChild 为自己找到了最简单的解决方案。

import { Component, ViewChild } from '@angular/core';

@Component({
  selector: 'cbtest',
  template: `
    <input type="text" #inp/>
    <input type="button" (click)="copy ()" value="copy now"/>`
})

export class CbTestComponent
{
  @ViewChild ("inp") inp : any;

  copy ()
  {
    // this.inp.nativeElement.value = "blabla";  // you can set a value manually too

    this.inp.nativeElement.select ();   // select
    document.execCommand ("copy");      // copy
    this.inp.nativeElement.blur ();     // unselect
  }
}

0
投票

以下@Sangram 的回答(以及@Jonathan 的评论)的解决方案 1:

(赞成“不要在角度中使用普通文档”和“如果不需要,请不要从代码中添加 HTML 元素……)

// TS

@ViewChild('textarea') textarea: ElementRef;

constructor(@Inject(DOCUMENT) private document: Document) {}

public copyToClipboard(text): void {
  console.log(`> copyToClipboard(): copied "${text}"`);
  this.textarea.nativeElement.value = text;
  this.textarea.nativeElement.focus();
  this.textarea.nativeElement.select();
  this.document.execCommand('copy');
}
/* CSS */
.textarea-for-clipboard-copy {
  left: -10000;
  opacity: 0;
  position: fixed;
  top: -10000;
}
<!-- HTML -->
<textarea class="textarea-for-clipboard-copy" #textarea></textarea>


0
投票

更容易enter image description here

let textToCopy: string = `\nAccess Token: ${conn.accessToken} \nInstance Url: ${conn.instanceUrl} \nOrg ID: ${conn.userInfo.organizationId}`;

navigator.clipboard.writeText(textToCopy.trim());


-2
投票
copyCurl(val: string){
    navigator.clipboard.writeText(val).then( () => {
      this.toastr.success('Text copied to clipboard');
    }).catch( () => {
      this.toastr.error('Failed to copy to clipboard');
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.