JavaScript Clipboard API
Die moderne asynchrone JavaScript Clipboard API — Text mit navigator.clipboard lesen und kopieren, Rich-Data mit ClipboardItem verwalten und Sicherheitsanforderungen beachten.
Die moderne Clipboard API, die über navigator.clipboard bereitgestellt wird, ist die asynchrone, Promise-basierte Methode zum Lesen aus und Schreiben in die Systemzwischenablage. Sie ersetzt den alten, synchronen Ansatz document.execCommand('copy') durch Methoden, die Promises zurückgeben und sich daher gut mit async/await kombinieren lassen. Die API ist von den cut-, copy- und paste-Ereignissen der Zwischenablage zu unterscheiden — wird aber häufig gemeinsam mit ihnen verwendet: Die Ereignisse ermöglichen es, Benutzeraktionen abzufangen, während navigator.clipboard es Ihrem Code erlaubt, Zwischenablage-Aktionen direkt einzuleiten.
Text in die Zwischenablage schreiben
Die häufigste Aufgabe ist das Kopieren von Text. navigator.clipboard.writeText(text) nimmt einen string entgegen, schreibt ihn in die Zwischenablage und gibt ein Promise zurück, das aufgelöst wird, wenn der Schreibvorgang erfolgreich war, und abgelehnt wird, wenn er fehlschlägt.
Da es ein Promise zurückgibt, ist die übersichtlichste Verwendung innerhalb einer async-Funktion mit try...catch, damit Sie dem Benutzer in jedem Fall Rückmeldung geben können:
<button id="copyBtn">Copy</button>
<span id="status"></span>
<script>
const button = document.getElementById('copyBtn');
const status = document.getElementById('status');
button.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText('Hello from W3docs!');
status.textContent = 'Copied!';
} catch (err) {
status.textContent = 'Copy failed';
console.error('Clipboard write failed:', err);
}
});
</script>Das await pausiert, bis der Schreibvorgang in die Zwischenablage abgeschlossen ist. Wenn der Benutzer die Berechtigung verweigert hat oder die Seite sich nicht in einem sicheren Kontext befindet, wird das Promise abgelehnt und der catch-Block wird ausgeführt — weshalb Sie niemals davon ausgehen sollten, dass das Kopieren erfolgreich war.
Text aus der Zwischenablage lesen
Um den aktuellen Text der Zwischenablage zu lesen, rufen Sie navigator.clipboard.readText() auf. Es gibt ebenfalls ein Promise zurück, diesmal mit dem Textinhalt der Zwischenablage als Ergebnis:
<button id="pasteBtn">Read clipboard</button>
<p id="output"></p>
<script>
const button = document.getElementById('pasteBtn');
const output = document.getElementById('output');
button.addEventListener('click', async () => {
try {
const text = await navigator.clipboard.readText();
output.textContent = `Clipboard contains: ${text}`;
} catch (err) {
output.textContent = 'Could not read clipboard';
console.error('Clipboard read failed:', err);
}
});
</script>Das Lesen ist weitaus sensibler als das Schreiben, da es den Inhalt offenlegt, den der Benutzer kopiert hat — möglicherweise ein Passwort oder andere private Daten. Aus diesem Grund schützen Browser readText() strenger: Es erfordert eine explizite Benutzerinteraktion, und einige Browser zeigen beim ersten Mal eine Berechtigungsanfrage an oder erlauben das Lesen nur, wenn der Seitentab fokussiert ist.
Anforderungen und häufige Fallstricke
Die Clipboard API hat mehrere Regeln, die — wenn ignoriert — zu stillen Ablehnungen führen. Behalten Sie diese im Hinterkopf, wenn Sie sie verwenden.
Die Clipboard API funktioniert nur in einem sicheren Kontext — das bedeutet HTTPS oder localhost während der Entwicklung. Auf einer einfachen http://-Seite ist navigator.clipboard in der Regel undefined. Aufrufe erfordern außerdem generell eine Benutzerinteraktion wie einen Klick oder Tastendruck, sodass sie beim Laden der Seite fehlschlagen. Die Permissions API regelt die Berechtigungen clipboard-read und clipboard-write, und Lesevorgänge können den Benutzer um Erlaubnis bitten. Da jeder Aufruf abgelehnt werden kann — durch verweigerte Berechtigung, ein nicht fokussiertes Dokument oder einen nicht unterstützten Browser — sollten Sie Zwischenablage-Aufrufe immer in try...catch einwickeln.
Die Seite benötigt auch den Fokus für viele Zwischenablage-Operationen. Wenn Sie readText() beispielsweise aus einem setTimeout heraus aufrufen, während der Benutzer zu einem anderen Tab gewechselt hat, ist eine Ablehnung mit dem Fehler „document is not focused" zu erwarten. Beachten Sie außerdem, dass ein Lesevorgang aus der Zwischenablage erst möglich ist, nachdem der Benutzer Ihre Seite fokussiert und mit ihr interagiert hat.
Rich-Daten mit ClipboardItem kopieren
Text ist der einfache Fall. Um Nicht-Textdaten zu kopieren — Bilder, HTML oder mehrere Formate gleichzeitig — verwenden Sie navigator.clipboard.write(), das ein array von ClipboardItem-Objekten entgegennimmt. Jedes ClipboardItem ordnet MIME-Typen ihren Daten zu (typischerweise ein Blob).
Das folgende Beispiel lädt ein Bild, verpackt den resultierenden Blob in ein ClipboardItem und kopiert es:
async function copyImage(url) {
try {
const response = await fetch(url);
const blob = await response.blob();
const item = new ClipboardItem({ [blob.type]: blob });
await navigator.clipboard.write([item]);
console.log('Image copied to clipboard');
} catch (err) {
console.error('Failed to copy image:', err);
}
}Der Schlüssel im ClipboardItem-Konstruktor ist der MIME-Typ (hier blob.type, z. B. 'image/png'), und der Wert sind die Daten für diesen Typ. Ein einzelnes Element kann mehrere Repräsentationen enthalten — zum Beispiel sowohl 'text/plain' als auch 'text/html' — sodass die Zielanwendung die beste auswählen kann.
Das Lesen von Rich-Daten funktioniert analog mit navigator.clipboard.read(), das zu einem array von ClipboardItem-Objekten aufgelöst wird, die Sie nach Typ inspizieren:
async function readClipboardItems() {
const items = await navigator.clipboard.read();
for (const item of items) {
for (const type of item.types) {
const blob = await item.getType(type);
console.log(`Found ${type}`, blob);
}
}
}Die Browser-Unterstützung für Rich-Data-Methoden (write und read mit ClipboardItem) ist eingeschränkter und weniger einheitlich als für die Textmethoden. Bild-MIME-Typen variieren insbesondere je nach Browser — image/png ist am zuverlässigsten. Prüfen Sie mit if ('write' in navigator.clipboard) die Feature-Verfügbarkeit und greifen Sie auf das Kopieren von Text oder einer URL zurück, wenn Rich-Daten nicht verfügbar sind.
Der Legacy-Fallback
Vor der asynchronen API bedeutete Kopieren, ein Element auszuwählen und document.execCommand('copy') aufzurufen. Diese Methode ist inzwischen veraltet, funktioniert aber in älteren Browsern noch, sodass sie ausschließlich als Fallback nützlich ist. Das typische Muster wählte ein verstecktes <textarea>-Element aus und führte dann den Befehl aus:
function copyTextFallback(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy'); // deprecated
document.body.removeChild(textarea);
}Moderner Code sollte die asynchrone API bevorzugen und nur zurückfallen, wenn navigator.clipboard fehlt:
async function copyText(text) {
if (navigator.clipboard) {
await navigator.clipboard.writeText(text);
} else {
copyTextFallback(text);
}
}Praxisanwendungen
Die Clipboard API ermöglicht viele kleine, aber wertvolle Interaktionen, die Sie täglich sehen:
- „Code kopieren"-Schaltflächen auf Dokumentationsseiten, damit Leser einen Ausschnitt ohne manuelle Auswahl übernehmen können.
- „Link zum Teilen kopieren"-Schaltflächen, die eine URL in die Zwischenablage legen, um sie in Chats oder E-Mails einzufügen.
- Kopieren von generiertem Output, wie einem Passwort, einem API-Schlüssel oder einem formatierten Zitat.
Was auch immer Sie kopieren, geben Sie sichtbares Feedback. Eine Schaltfläche, die still kopiert, lässt Benutzer im Unklaren, ob es funktioniert hat. Ändern Sie die Beschriftung zu „Kopiert!", zeigen Sie einen kurzen Toast an oder aktualisieren Sie ein benachbartes Statuselement — das ist auch ein Gewinn für die Barrierefreiheit, da Bildschirmleser-Benutzer keinen Zwischenablage-Hinweis vom Browser selbst erhalten.