Cara menempelkan gambar

Harry Theodoulou
Harry Theodoulou

Cara modern

Menggunakan Async Clipboard API

Untuk membaca gambar dari papan klip pengguna secara terprogram, yaitu setelah tombol diklik, Anda dapat menggunakan metode read() dari Async Clipboard API. Jika izin untuk membaca dari papan klip belum diberikan, panggilan ke navigator.clipboard.read() akan memintanya saat panggilan pertama metode.

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);
  }
});

Dukungan Browser

  • 86
  • 79
  • 13,1

Sumber

Cara klasik

Proses peristiwa paste

Cara klasik untuk menempelkan gambar adalah dengan menggunakan Clipboard API (sinkron), yang memberi Anda akses ke kolom clipboardData di dalam Dokumen: peristiwa paste. Namun, metode ini memiliki batasan, misalnya karena metode ini sinkron, menempelkan data dalam jumlah besar dapat memblokir halaman.

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.
    }
  }
});

Dukungan Browser

  • 66
  • 79
  • 63
  • 13,1

Sumber

{i>Progressive enhancement <i}

Untuk browser yang tidak mendukung Async Clipboard API, Anda tidak dapat mengakses papan klip pengguna secara terprogram (misalnya, saat tombol diklik). Dengan demikian, untuk mengakses papan klip pengguna pada peristiwa paste, Anda dapat menggunakan Async Clipboard API dan kembali ke Clipboard API (sinkron).

Objek ClipboardItem yang berasal dari navigator.clipboard.read memiliki kolom types yang merupakan array, dan objek File yang berasal dari event.clipboardData.files memiliki kolom type yang berupa string. Anda dapat memeriksa secara kondisional setiap kolom type atau types untuk gambar di papan klip:

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.
      }
    }
  }
});

Bacaan lebih lanjut

  • Clipboard API di MDN
  • Berhenti memblokir akses papan klip di web.dev

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);
};