Angular 5 -复制到剪贴板

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

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

198096 次浏览

复制任何文本

超文本标记语言

<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:从文本框复制

超文本标记语言

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

Demo Here . .


导入第三方指令ngx-clipboard

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

解决方案4:自定义指令

如果你更喜欢使用自定义指令,请检查Dan Dohotaru的回答,这是一个使用ClipboardEvent实现的优雅解决方案。


方案五: Angular Material

Angular材质9 +的用户可以使用内置的剪贴板特性来复制文本。还有一些更多的定制可用,例如限制复制数据的尝试次数。

我认为在复制文本时,这是一个更干净的解决方案:

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

然后在html中的click事件上调用copyToClipboard(click)="copyToClipboard('texttocopy')"

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

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

然后像这样使用它

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

注意:IE需要window["clipboardData"],因为它不理解e.clipboardData

修改版本的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);
}

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

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

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

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

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

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

< a href = " https://material.angular。io/cdk/clipboard/overview" rel="noreferrer"> clipboard | Angular Material .

它可以简单地使用

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

你可以使用Angular模块来实现:

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

使用angular cdk复制,

Module.ts

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

以编程方式复制一个字符串:

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


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

点击一个元素通过HTML复制:

<button [cdkCopyToClipboard]="longText" [cdkCopyToClipboardAttempts]="2">Copy text</button>
< p >参考: https://material.angular.io/cdk/clipboard/overview < / p >

使用navigator.clipboard.writeText将内容复制到剪贴板

navigator.clipboard.writeText(content).then().catch(e => console.error(e));
// 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);
});
}

用纯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
}
}

对我来说,document.execCommand('copy')给出了< >强弃用< / >强警告,我需要复制的数据在<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));


}
}

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

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

(支持“不要在angular中使用普通文档”;和“如果你没有必要,不要从代码中添加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>

copyCurl(val: string){
navigator.clipboard.writeText(val).then( () => {
this.toastr.success('Text copied to clipboard');
}).catch( () => {
this.toastr.error('Failed to copy to clipboard');
});
}

很简单,兄弟

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