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