Estoy tratando de implementar un ícono que, al hacer clic, guardará una variable en el portapapeles del usuario. Actualmente he probado varias bibliotecas y ninguna de ellas ha podido hacerlo.
¿Cómo copio correctamente una variable en el portapapeles del usuario en Angular 5?
Solución 1: copia cualquier texto
HTML
<button (click)="copyMessage('This goes to Clipboard')" value="click to copy" >Copy this</button>
archivo .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); }
Solución 2: copiar desde un cuadro de texto
HTML
<input type="text" value="User input Text to copy" #userinput> <button (click)="copyInputMessage(userinput)" value="click to copy" >Copy from Textbox</button>
archivo .ts
/* To copy Text from Textbox */ copyInputMessage(inputElement){ inputElement.select(); document.execCommand('copy'); inputElement.setSelectionRange(0, 0); }
Solución 3: importar una directiva de terceros ngx-clipboard
<button class="btn btn-default" type="button" ngxClipboard [cbContent]="Text to be copied">copy</button>
Solución 4: Directiva personalizada
Si prefiere usar una directiva personalizada, consulte la respuesta de Dan Dohotaru, que es una solución elegante implementada con ClipboardEvent
.
Solución 5: Material Angular
Los usuarios de material angular 9 + pueden utilizar la función de portapapeles incorporada para copiar texto. Hay algunas personalizaciones más disponibles, como limitar el número de intentos de copiar datos.
Sé que esto ya ha sido muy votado aquí ahora, pero prefiero optar por un enfoque de directiva personalizado y confiar en el ClipboardEvent como sugirió @jockeisorby, mientras me aseguro de que el oyente se elimine correctamente (se debe proporcionar la misma función tanto para agregar como para eliminar detectores de eventos)
demostración de 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); } }
y luego usarlo como tal
<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`); }
Nota: observe que se necesita la window["clipboardData"]
para IE, ya que no comprende e.clipboardData
Creo que esta es una solución mucho más limpia al copiar texto:
copyToClipboard(item) { document.addEventListener('copy', (e: ClipboardEvent) => { e.clipboardData.setData('text/plain', (item)); e.preventDefault(); document.removeEventListener('copy', null); }); document.execCommand('copy'); }
Y luego simplemente llame a copyToClipboard
al hacer clic en el evento en html. (click)="copyToClipboard('texttocopy')"
.