Вот элегантное решение для Angular 5.x +:
Компонент:
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
Input,
OnInit,
Output,
Renderer2,
ViewChild
} from '@angular/core';
@Component({
selector: 'copy-to-clipboard',
templateUrl: './copy-to-clipboard.component.html',
styleUrls: ['./copy-to-clipboard.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CopyToClipboardComponent implements OnInit {
@ViewChild('input') input: ElementRef;
@Input() size = 'md';
@Input() theme = 'complement';
@Input() content: string;
@Output() copied: EventEmitter<string> = new EventEmitter<string>();
@Output() error: EventEmitter<string> = new EventEmitter<string>();
constructor(private renderer: Renderer2) {}
ngOnInit() {}
copyToClipboard() {
const rootElement = this.renderer.selectRootElement(this.input.nativeElement);
// iOS Safari blocks programmtic execCommand copying normally, without this hack.
// https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
this.renderer.setAttribute(this.input.nativeElement, 'contentEditable', 'true');
const range = document.createRange();
range.selectNodeContents(this.input.nativeElement);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
rootElement.setSelectionRange(0, 999999);
} else {
rootElement.select();
}
try {
document.execCommand('copy');
this.copied.emit();
} catch (err) {
this.error.emit(err);
}
};
}
Шаблон:
<button class="btn btn-{{size}} btn-{{theme}}" type="button" (click)="copyToClipboard()">
<ng-content></ng-content>
</button>
<input #input class="hidden-input" [ngModel]="content">
Стили:
.hidden-input {
position: fixed;
top: 0;
left: 0;
width: 1px;
height: 1px;
padding: 0;
border: 0;
box-shadow: none;
outline: none;
background: transparent;
}