Kopieerknop naar klembord in JavaScript en React | We.Inc
Bouw een kopieerknop met navigator.clipboard.writeText: een werkende demo, een React-hook, opgemaakte HTML en afbeeldingen kopiëren met ClipboardItem, toegankelijke Gekopieerd-feedback en foutafhandeling.
Roep navigator.clipboard.writeText(text) aan vanuit een klikhandler. Het geeft een promise terug, dus gebruik await, toon daarna een korte melding Gekopieerd en vang de foutsituatie af. De API werkt alleen op HTTPS of localhost en vereist een echte gebruikersactie zoals een klik, dus roep hem niet aan bij het laden van de pagina.
Een kopieerknop lijkt triviaal, maar de snippets die hoog scoren slaan vaak de delen over die misgaan: de promise kan rejecten, ingesloten frames kunnen geblokkeerd worden en gebruikers van een schermlezer horen nooit dat er iets is gebeurd. De demo hieronder kopieert echt in uw browser, en de code dekt elk van die gevallen.
Druk in de demo op een knop Kopiëren. Het label wisselt twee seconden naar Gekopieerd en een verborgen statusmelding kondigt het aan.
Plak in het testvak om precies te controleren wat er op uw klembord is beland.
Probeer de knop voor opgemaakte tekst en plak daarna in een e-mail of documenteditor om te zien dat de HTML-versie de opmaak behoudt.
Kopieer hieronder het gewone JavaScript, de React-hook of de code voor opgemaakt kopiëren.
Handel een rejection altijd af. Toon iets als Druk op Ctrl+C om te kopiëren en selecteer de tekst, zodat de persoon het met de hand kan afmaken.
Kondig succes aan met een regio met role="status". Alleen een icoon wijzigen vertelt gebruikers van een schermlezer niets.
Houd de breedte van het knoplabel stabiel als het naar Gekopieerd wisselt, zodat er niets omheen verspringt.
Kopieer de waarde uit uw data, niet uit innerText van een gestyled element, dat verborgen of extra witruimte kan oppikken.
Binnen een iframe moet de parent in Chromium clipboard-write toestaan via Permissions Policy, bijvoorbeeld allow="clipboard-write".
Veelgestelde vragen
Waarom is navigator.clipboard undefined?
De pagina draait niet in een beveiligde context. De Clipboard API is alleen beschikbaar op HTTPS-pagina's en op localhost, dus een site die via gewoon HTTP of vanaf een lokaal netwerkadres wordt geserveerd, heeft hem niet.
Waarom geeft writeText een NotAllowedError?
De browser weigerde het schrijven, meestal omdat er geen recente gebruikersactie was, de pagina geen focus had of een frame werd geblokkeerd door Permissions Policy. Roep het direct aan in een klikhandler en vermijd lange awaits ervoor.
Heb ik een library nodig om in React naar het klembord te kopiëren?
Nee. Een hook van tien regels rond navigator.clipboard.writeText volstaat. Libraries voegen vooral een execCommand-fallback toe voor heel oude browsers, die huidige browsers niet nodig hebben.
Kan ik een afbeelding naar het klembord kopiëren?
Ja, met navigator.clipboard.write en een ClipboardItem met als sleutel image/png en als waarde een PNG-Blob. Gebruik ClipboardItem.supports() om eerst een type te controleren; PNG is het formaat dat browsers het betrouwbaarst accepteren.
Is document.execCommand('copy') nog in orde?
Het is verouderd. Het werkt in veel browsers nog onder wisselende voorwaarden, maar nieuwe code hoort de asynchrone Clipboard API te gebruiken, met als fallback de vraag aan de persoon om handmatig te kopiëren.
De drie regels die de browser afdwingt
Naar het klembord schrijven is een bevoorrechte actie, dus browsers vereisen een beveiligde pagina, een document met focus en, in Firefox en Safari, een verse gebruikersactie voor elke schrijfactie. Chromium kan ook een blijvende clipboard-write-permissie verlenen.
In de praktijk start u het kopiëren vanuit een klik of toetsaanslag, schrijft u vroeg in de handler en behandelt u mislukken als normaal en niet als uitzondering.
Feedback die mensen kunnen waarnemen
Wissel het label ongeveer twee seconden naar Gekopieerd en zet het daarna terug. Een tooltip die alleen bij hover verschijnt, is onzichtbaar op touchscreens en voor toetsenbordgebruikers.
Zet dezelfde melding in een beleefde live region. role="status" kondigt hem aan zonder te onderbreken wat de schermlezer aan het voorlezen was.
Opgemaakte kopieën en eigen copy-events
Een ClipboardItem kan tegelijk een versie text/plain en text/html bevatten. Apps die HTML begrijpen plakken de opgemaakte versie, velden voor platte tekst nemen de andere.
Om te wijzigen wat een gewone Ctrl+C kopieert, zoals een bronregel toevoegen, luistert u naar het copy-event, roept u event.preventDefault() aan en zet u uw eigen data met event.clipboardData.setData().
Gewoon JavaScript
Kopieerknop met feedback en een fallback
Het statuselement is visueel verborgen maar wordt voorgelezen. Bij een fout wordt de tekst geselecteerd, zodat de persoon op Ctrl+C of Cmd+C kan drukken.
React-hook
useCopyToClipboard
Geeft de status en een kopieerfunctie terug. De timer wordt bij unmount gewist, zodat hij nooit een verwijderde component bijwerkt.
Opgemaakte tekst, afbeeldingen en het copy-event
HTML kopiëren met platte tekst als fallback
Elk MIME-type is een Blob. Plakdoelen kiezen het rijkste formaat dat ze begrijpen.
Een bronregel toevoegen aan gewone kopieën
Gebruik dit spaarzaam. Wijzigen wat mensen kopiëren kan irriteren, dus beperk het tot citaten of code waar een bron helpt.
Fouten en hun oorzaken
Als kopiëren mislukt
Wat u ziet
Waarschijnlijke oorzaak
Oplossing
navigator.clipboard is undefined
Pagina geserveerd via gewoon HTTP
Serveer via HTTPS, of test op localhost
NotAllowedError
Geen gebruikersactie, of het tabblad heeft geen focus
Roep het aan in de klikhandler
NotAllowedError in een iframe
Permissions Policy blokkeert clipboard-write
Voeg allow="clipboard-write" toe aan de iframe
Kopiëren van afbeelding geweigerd
Niet-ondersteund MIME-type
Converteer naar PNG en controleer ClipboardItem.supports()
Gekopieerd
Mislukt
Kopiëren
Opgemaakte tekst kopiëren
Gekopieerd naar klembord
Kopiëren mislukt. Selecteer de tekst en druk op Ctrl+C of Cmd+C.
Probeer het
Kopieerknoppen voor platte tekst en opgemaakte HTML, met een plakvak om het resultaat te controleren.