Resimleri yapıştırma

Harry Theodoulou
Harry Theodoulou

Modern yöntem

Async Clipboard API'yi kullanma

Kullanıcının panosundaki resimleri programatik olarak okumak için (bir düğmeyi tıkladıktan sonra) Async Clipboard API'nin read() yöntemini kullanabilirsiniz. Panodan okuma izni henüz verilmediyse navigator.clipboard.read() çağrısı, yöntemin ilk çağrısında bu izni ister.

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

Tarayıcı Desteği

  • 86
  • 79
  • 13.1

Kaynak

Klasik yöntem

paste etkinliğini dinle

Resim yapıştırmanın klasik yolu, Doküman: paste etkinliği içindeki clipboardData alanına erişmenizi sağlayan (eşzamanlı) Clipboard API'yi kullanmaktır. Ancak bu yöntemin bazı sınırlamaları vardır. Örneğin, eşzamanlı olduğu için büyük miktarda veri yapıştırmak sayfayı engelleyebilir.

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

Tarayıcı Desteği

  • 66
  • 79
  • 63
  • 13.1

Kaynak

Progresif geliştirme

Async Clipboard API'yi desteklemeyen tarayıcılarda kullanıcının panosuna programlı bir şekilde erişmek mümkün değildir (örneğin, bir düğmeyi tıklayarak). Böylece, bir paste etkinliğinde kullanıcının panosuna erişmek için Async Clipboard API'yi kullanabilir ve (eşzamanlı) Clipboard API'ye geri dönebilirsiniz.

navigator.clipboard.read öğesinden gelen ClipboardItem nesnelerinde dizi olan bir types alanı, event.clipboardData.files kaynağından gelen File nesnelerin ise dize olan bir type alanı var. Panodaki resimler için type veya types alanlarının her birini koşullu olarak kontrol edebilirsiniz:

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

Daha fazla bilgi

  • MDN'de Clipboard API
  • web.dev'de pano erişiminin engeli kaldırılıyor

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