Pulsante copia negli appunti in JavaScript e React | We.Inc
Crea un pulsante copia con navigator.clipboard.writeText: demo funzionante, un hook React, copia di HTML formattato e immagini con ClipboardItem, feedback Copiato accessibile ed errori.
Chiama navigator.clipboard.writeText(text) da un gestore di clic. Restituisce una promise, quindi usa await, poi mostra un breve messaggio Copiato e gestisci il caso di errore. L'API funziona solo su HTTPS o localhost e richiede una vera azione dell'utente come un clic, quindi non chiamarla al caricamento della pagina.
Un pulsante copia sembra banale, eppure gli snippet che si posizionano meglio spesso saltano le parti che vanno storte: la promise può essere rifiutata, i frame incorporati possono essere bloccati e gli utenti di screen reader non sentono mai che è successo qualcosa. La demo qui sotto copia davvero nel tuo browser, e il codice copre ognuno di questi casi.
Premi un pulsante Copia nella demo. L'etichetta diventa Copiato per due secondi, e un messaggio di stato nascosto lo annuncia.
Incolla nella casella di prova per verificare esattamente cosa è finito negli appunti.
Prova il pulsante di copia formattata, poi incolla in un'email o in un editor di documenti per vedere la versione HTML mantenere la formattazione.
Copia qui sotto il codice JavaScript puro, l'hook React o il codice per la copia formattata.
Gestisci sempre il rifiuto. Mostra qualcosa come Premi Ctrl+C per copiare e seleziona il testo, così la persona può finire a mano.
Annuncia il successo con una regione role="status". Cambiare solo un'icona non dice nulla agli utenti di screen reader.
Mantieni stabile la larghezza dell'etichetta del pulsante quando passa a Copiato, così nulla intorno salta.
Copia il valore dai tuoi dati, non dall'innerText di un elemento con stili, che può includere spazi nascosti o in più.
Dentro un iframe, Chromium richiede che il genitore consenta clipboard-write tramite Permissions Policy, per esempio allow="clipboard-write".
Domande frequenti
Perché navigator.clipboard è undefined?
La pagina non è in un contesto sicuro. La Clipboard API è disponibile solo sulle pagine HTTPS e su localhost, quindi un sito servito in HTTP semplice o da un indirizzo di rete locale non la avrà.
Perché writeText genera NotAllowedError?
Il browser ha rifiutato la scrittura, di solito perché non c'è stata un'azione recente dell'utente, la pagina non aveva il focus o un frame è stato bloccato dalla Permissions Policy. Chiamala direttamente dentro un gestore di clic ed evita lunghi await prima.
Mi serve una libreria per copiare negli appunti in React?
No. Un hook di dieci righe attorno a navigator.clipboard.writeText basta. Le librerie aggiungono soprattutto un fallback con execCommand per browser molto vecchi, di cui i browser attuali non hanno bisogno.
Posso copiare un'immagine negli appunti?
Sì, con navigator.clipboard.write e un ClipboardItem la cui chiave è image/png e il cui valore è un Blob PNG. Usa prima ClipboardItem.supports() per verificare un tipo; PNG è il formato che i browser accettano in modo più affidabile.
document.execCommand('copy') va ancora bene?
È deprecato. Funziona ancora in molti browser in condizioni variabili, ma il codice nuovo dovrebbe usare la Clipboard API asincrona, ripiegando sul chiedere alla persona di copiare manualmente.
Le tre regole che il browser impone
Scrivere negli appunti è un'azione privilegiata, quindi i browser richiedono una pagina sicura, un documento con il focus e, in Firefox e Safari, un gesto recente dell'utente per ogni scrittura. Chromium può anche concedere un permesso clipboard-write permanente.
In pratica, avvia la copia da un clic o dalla pressione di un tasto, esegui la scrittura all'inizio del gestore e tratta il fallimento come normale invece che come eccezionale.
Un feedback che le persone possono percepire
Cambia l'etichetta in Copiato per circa due secondi e poi ripristinala. Un tooltip che appare solo al passaggio del mouse è invisibile sui touch screen e per chi usa la tastiera.
Metti lo stesso messaggio in una live region educata. role="status" lo annuncia senza interrompere ciò che lo screen reader stava leggendo.
Copie formattate ed eventi copy personalizzati
Un ClipboardItem può contenere insieme una versione text/plain e una text/html. Le app che capiscono l'HTML incollano quella formattata, i campi di testo semplice prendono l'altra.
Per cambiare ciò che copia un normale Ctrl+C, per esempio aggiungendo una riga con la fonte, ascolta l'evento copy, chiama event.preventDefault() e imposta i tuoi dati con event.clipboardData.setData().
JavaScript puro
Pulsante copia con feedback e un fallback
L'elemento di stato è nascosto alla vista ma viene letto ad alta voce. In caso di errore il testo viene selezionato così la persona può premere Ctrl+C o Cmd+C.
Hook React
useCopyToClipboard
Restituisce lo stato e una funzione di copia. Il timer viene cancellato allo smontaggio, così non aggiorna mai un componente rimosso.
Testo formattato, immagini e l'evento copy
Copiare HTML con un fallback in testo semplice
Ogni tipo MIME è un Blob. Le destinazioni dell'incolla scelgono il formato più ricco che capiscono.
Aggiungere una riga con la fonte alle copie normali
Usalo con parsimonia. Cambiare ciò che le persone copiano può infastidirle, quindi limitalo a citazioni o codice dove una fonte è utile.
Errori e loro cause
Quando la copia fallisce
Cosa vedi
Causa probabile
Soluzione
navigator.clipboard è undefined
Pagina servita in HTTP semplice
Servila in HTTPS, o prova su localhost
NotAllowedError
Nessun gesto dell'utente, o la scheda non ha il focus
Chiamala dentro il gestore di clic
NotAllowedError dentro un iframe
La Permissions Policy blocca clipboard-write
Aggiungi allow="clipboard-write" sull'iframe
Copia dell'immagine rifiutata
Tipo MIME non supportato
Converti in PNG e controlla ClipboardItem.supports()
Copiato
Non riuscito
Copia
Copia testo formattato
Copiato negli appunti
Copia non riuscita. Seleziona il testo e premi Ctrl+C o Cmd+C.
Provalo
Pulsanti copia per testo semplice e HTML formattato, con una casella in cui incollare per verificare il risultato.