In die Zwischenablage kopieren mit der Clipboard API
Ein Kopieren-Button ist eine Kleinigkeit, die Nutzer sofort bemerken – Rechnungsnummer, Gutscheincode, Link. document.execCommand ist dafür veraltet; navigator.clipboard ist der heutige Weg, braucht aber HTTPS und eine echte Nutzergeste.
Es gibt Funktionen, die kosten zehn Minuten und werden trotzdem jedes Mal bemerkt. Ein Kopieren-Knopf neben einer Rechnungsnummer, einem Einladungslink oder einem Gutscheincode gehört dazu — die Alternative ist markieren, aus Versehen daneben tippen, nochmal markieren.
Die heutige Fassung
async function kopiere(text, knopf) {
try {
await navigator.clipboard.writeText(text);
knopf.textContent = 'Kopiert ✓';
} catch (e) {
knopf.textContent = 'Ging nicht 😕';
}
setTimeout(() => { knopf.textContent = 'Kopieren'; }, 1600);
}
document.querySelectorAll('[data-kopieren]').forEach((btn) => {
btn.addEventListener('click', () => kopiere(btn.dataset.kopieren, btn));
});writeText gibt ein Promise zurück, deshalb await. Und es kann fehlschlagen — deshalb try/catch. Beides ist kein Zierrat.
Drei Bedingungen, die erfüllt sein müssen
- Sicherer Kontext. Die Seite muss über HTTPS laufen (oder
localhost). Auf einer reinenhttp://-Seite istnavigator.clipboardschlichtundefined— dein Skript stirbt dann anCannot read properties of undefined. - Eine echte Nutzergeste. Der Aufruf muss aus einem Klick oder Tastendruck heraus kommen. Beim Laden der Seite ungefragt etwas in die Zwischenablage schreiben — genau das soll die Regel verhindern.
- Kein zu langer Umweg. Wer erst noch auf einen
fetchwartet und danach kopiert, verliert in manchen Browsern den Bezug zur Geste. Text vorher bereitlegen, dann kopieren.
Deshalb prüfe ich vorher, ob es die API überhaupt gibt:
if (!navigator.clipboard) {
knopf.hidden = true; // lieber kein Knopf als ein kaputter
}Das ist mir lieber als der alte document.execCommand('copy')-Umweg mit einem unsichtbaren Textfeld. Der ist offiziell veraltet, und einen Knopf zu zeigen, der nichts tut, ist schlimmer als gar keiner.
Aus der Zwischenablage lesen
const text = await navigator.clipboard.readText();Das ist der Teil, bei dem der Browser den Nutzer um Erlaubnis fragt — und zwar zu Recht: In der Zwischenablage steht oft ein Passwort. Ich baue das nur ein, wenn es einen offensichtlichen Grund gibt, etwa ein „Code einfügen"-Feld. Sonst lasse ich es weg.
Die Rückmeldung ist der eigentliche Punkt
Kopieren ist unsichtbar. Ohne Rückmeldung tippt der Nutzer zweimal, weil er nicht weiß, ob es geklappt hat. Deshalb ändert sich in dem Beispiel oben der Text des Knopfes für anderthalb Sekunden. Das reicht völlig — Animation, Toast oder Icon-Wechsel gehen genauso, Hauptsache es passiert überhaupt etwas.
Auf meinen Seiten sitzt genau so ein Knopf am Einladungslink im Admin-Bereich: eine winzige Funktion, die man jeden Tag benutzt. Solche Kleinigkeiten machen den Unterschied zwischen „funktioniert" und „macht Freude".
Du hast eine Stelle in deiner Website oder deinem Backend, an der ständig etwas von Hand abgetippt wird? Das ist meistens in einer halben Stunde erledigt. Schreib mir.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
ResizeObserver – auf die Größe eines Elements reagieren, nicht auf die des Fensters
window.onresize feuert nur, wenn sich das Fenster ändert – nicht, wenn eine Seitenleiste aufklappt oder Text nachlädt. ResizeObserver meldet dir die Größe des Elements selbst, und zwar ohne Endlosschleife.
Aufzählungen richtig verketten mit Intl.ListFormat
"a, b und c" von Hand zusammenzubauen geht fast immer schief – bei einem Element, bei zwei Elementen, beim letzten Komma. Intl.ListFormat macht es richtig, in jeder Sprache, ganz ohne Bibliothek.
requestAnimationFrame – die Animationsschleife, die zum Bildschirm passt
setInterval(schritt, 16) läuft auf einem 144-Hz-Monitor anders als auf einem alten Handy – und im Hintergrundtab einfach weiter. requestAnimationFrame löst beides, wenn man die verstrichene Zeit mitrechnet statt Bilder zu zählen.