Cách sao chép hình ảnh

Nhiều trình duyệt hiện đại hỗ trợ sao chép hình ảnh vào bảng nhớ tạm ở các định dạng PNG và SVG. Các định dạng khác chưa được hỗ trợ vì lý do bảo mật.

Phong cách hiện đại

Sử dụng API Bảng nhớ tạm không đồng bộ

Phương thức Clipboard.write() lấy một mảng các đối tượng ClipboardItem và trả về một Hứa hẹn sẽ phân giải khi hình ảnh được ghi thành công vào bảng nhớ tạm. Chỉ có thể sử dụng Clipboard.write() từ đối tượng window có tâm điểm.

Hỗ trợ trình duyệt

  • 66
  • 79
  • 13,1

Nguồn

Cách cổ điển

Sử dụng navigator.clipboard.writeText()

Mặc dù không phải trình duyệt nào cũng hỗ trợ navigator.clipboard.write() cho dữ liệu nhị phân, nhưng tất cả đều hỗ trợ navigator.clipboard.writeText(). Nếu muốn sao chép hình ảnh SVG, thay vì sao chép chính hình ảnh, bạn có thể sao chép mã nguồn SVG. Đối với hình ảnh PNG, rất tiếc là bạn không gặp may.

Hỗ trợ trình duyệt

  • 66
  • 79
  • 63
  • 13,1

Nguồn

Nâng cao dần dần

const button = document.querySelector('button');
const img = document.querySelector('img');

button.addEventListener('click', async () => {
  const responsePromise = fetch(img.src);
  try {
    if ('write' in navigator.clipboard) {
      await navigator.clipboard.write([
        new ClipboardItem({
          'image/svg+xml': new Promise(async (resolve) => {
            const blob = await responsePromise.then(response => response.blob());
            resolve(blob);
          }),
        }),
      ]);
      // Image copied as image.
    } else {
      const text = await responsePromise.then(response => response.text());
      await navigator.clipboard.writeText(text);
      // Image copied as source code.
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});

Tài liệu đọc thêm

Bản minh họa

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 copy images</title>
  </head>
  <body>
    <h1>How to copy images</h1>
    <img src="assets/fugu.svg" alt="Fugu fish." width="128" height="128">
    <button type="button">Copy</button>
  </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


        const button = document.querySelector('button');
const img = document.querySelector('img');

button.addEventListener('click', async () => {
  const responsePromise = fetch(img.src);

  try {
    if ('write' in navigator.clipboard) {
      await navigator.clipboard.write([
        new ClipboardItem({
          'image/svg+xml': new Promise(async (resolve) => {
            const blob = await responsePromise.then(response => response.blob());
            resolve(blob);
          }),
        }),
      ]);
      // Image copied as image.
    } else {
      const text = await responsePromise.then(response => response.text());
      await navigator.clipboard.writeText(text);
      // Image copied as source code.
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});