Bilder einfügen

Harry Theodoulou
Harry Theodoulou

Die moderne Art

Async Clipboard API verwenden

Wenn Sie Bilder programmatisch aus der Zwischenablage des Nutzers lesen möchten, d. h. nach einem Klick auf eine Schaltfläche, können Sie die Methode read() der Async Clipboard API verwenden. Wenn die Berechtigung zum Lesen aus der Zwischenablage noch nicht gewährt wurde, wird sie beim ersten Aufruf der Methode durch den Aufruf von navigator.clipboard.read() angefordert.

const pasteButton = document.querySelector('#paste-button');

pasteButton.addEventListener('click', async () => {
  try {
    const clipboardItems = await navigator.clipboard.read();
    for (const clipboardItem of clipboardItems) {
      const imageTypes = clipboardItem.types.find(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        const blob = await clipboardItem.getType(imageType);
        // Do something with the image blob.
      }
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});

Unterstützte Browser

  • 86
  • 79
  • 13.1

Quelle

Die klassische Art

Auf das Ereignis paste warten

Die klassische Methode zum Einfügen von Bildern ist die (synchrone) Clipboard API, die Ihnen Zugriff auf das Feld clipboardData im Ereignis Dokument: paste gewährt. Diese Methode ist jedoch mit Einschränkungen verbunden. Beispielsweise kann die Seite durch das Einfügen großer Datenmengen blockiert werden, da sie synchron ist.

document.addEventListener('paste', async (e) => {
  e.preventDefault();

  for (const clipboardItem of e.clipboardData.files) {
    if (clipboardItem.type.startsWith('image/')) {
      // Do something with the image file.
    }
  }
});

Unterstützte Browser

  • 66
  • 79
  • 63
  • 13.1

Quelle

Progressive Enhancement

Bei Browsern, die die Async Clipboard API nicht unterstützen, ist es nicht möglich, programmatisch auf die Zwischenablage des Nutzers zuzugreifen (z. B. durch Klicken auf eine Schaltfläche). Wenn Sie also bei einem paste-Ereignis auf die Zwischenablage eines Nutzers zugreifen möchten, können Sie die Async Clipboard API verwenden und auf die (synchrone) Clipboard API zurückgreifen.

Die ClipboardItem-Objekte aus navigator.clipboard.read haben ein types-Feld, das ein Array ist, und File-Objekte aus event.clipboardData.files haben ein type-Feld, das ein String ist. Sie können jedes der Felder type oder types unter bestimmten Bedingungen auf Bilder in der Zwischenablage prüfen:

document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const clipboardItems = typeof navigator?.clipboard?.read === 'function' ? await navigator.clipboard.read() : e.clipboardData.files;

  for (const clipboardItem of clipboardItems) {
    let blob;
    if (clipboardItem.type?.startsWith('image/')) {
      // For files from `e.clipboardData.files`.
      blob = clipboardItem
      // Do something with the blob.
    } else {
      // For files from `navigator.clipboard.read()`.
      const imageTypes = clipboardItem.types?.filter(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        blob = await clipboardItem.getType(imageType);
        // Do something with the blob.
      }
    }
  }
});

Weitere Informationen

  • Clipboard API im MDN
  • Blockierung des Zugriffs auf die Zwischenablage auf web.dev aufheben

Demo

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
    />
    <title>How to paste images</title>
  </head>
  <body>
    <h1>How to paste images</h1>
    <p>Hit <kbd>⌘</kbd> + <kbd>v</kbd> (for macOS) or <kbd>ctrl</kbd> + <kbd>v</kbd>
      (for other operating systems) to paste images anywhere in this page.
    </p>
  </body>
</html>

CSS


        :root {
  color-scheme: dark light;
}

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

button {
  display: block;
}
        

JS


        document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const clipboardItems = typeof navigator?.clipboard?.read === 'function' ? await navigator.clipboard.read() : e.clipboardData.files;

  for (const clipboardItem of clipboardItems) {
    let blob;
    if (clipboardItem.type?.startsWith('image/')) {
      // For files from `e.clipboardData.files`.
      blob = clipboardItem
      // Do something with the blob.
      appendImage(blob);
    } else {
      // For files from `navigator.clipboard.read()`.
      const imageTypes = clipboardItem.types?.filter(type => type.startsWith('image/'))
      for (const imageType of imageTypes) {
        blob = await clipboardItem.getType(imageType);
        // Do something with the blob.
        appendImage(blob);
      }
    }
  }
});

const appendImage = (blob) => {
  const img = document.createElement('img');
  img.src = URL.createObjectURL(blob);
  document.body.append(img);
};