In Safari browser, you can directly use navigator.clipboard.writeText
to copy text without any issues. However, if you use navigator.clipboard.writeText
after a promise, it will throw a permission error. The specific error is as follows:
Unhandled Rejection (NotAllowedError): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Reasons:
- The copied content in development is requested through an interface, which Safari rejects. Due to security restrictions, the above method only works when the user interacts with the page. If your copy operation is not triggered by the user (for example, through a timer or other non-interactive means), it may be restricted by the browser.
- Accessing the clipboard through
document.execCommand()
is synchronous and can only read and write the DOM.
Clipboard API#
A new asynchronous copy and paste API. It provides (if the user grants permission) access to read and write system clipboard content. The Clipboard API can be used to implement cut, copy, and paste functionality in web applications by simply calling the
writeText
method to successfully copy a piece of text. This API is intended to replace accessing the clipboard using document.execCommand.
Copy: Writing content to the clipboard#
writeText()
To write text to the system clipboard, you can call writeText()
. The text will be successfully copied and can be pasted using Ctrl+V.
async function copyText(text) {
try {
await navigator.clipboard.writeText(text)
console.log('The page content has been copied to the clipboard')
} catch (e) {
console.log(`Failed to copy text: ${e}`)
}
}
write()
In fact, writeText()
is just a shorthand for the generic write()
method, which also allows you to copy images to the clipboard. After successfully copying an image, it needs to be read using the read()
method. The write()
method accepts an array of ClipboardItem
objects as a parameter. To create a new ClipboardItem
object, you need to use the MIME type as the key and a Blob
as the value.
Currently, support for multiple ClipboardItems
is not implemented, but support for multiple key-value pairs of data is supported.
const data = new ClipboardItem({
// [MIME]: Blob
'image/png': Blob,
'text/plain': Blob
})
// Supported
await navigator.clipboard.write([data]);
// Not supported
await navigator.clipboard.write([data, data]);
Note: Since the Clipboard API is still an experimental API, it behaves differently in Safari browser.
- It must be in an HTTPS environment to be debugged and used. Otherwise, an error will occur: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
- The
blob
property value ofClipboardItem
needs to return a Promise.
const data = new ClipboardItem({
'text/plain': new Promise((resolve) => {
resolve(new Blob(['example text'], { type: 'text/plain' }))
})
})
Paste: Reading data from the clipboard#
readText()
To read text from the clipboard, you can call readText()
.
async function getClipboardText() {
try {
const text = await navigator.clipboard.readText();
console.log(`Pasted content: ${text}`);
// Some operations
} catch (e) {
console.error(`Failed to get data from the clipboard: ${e}`);
}
}
read()
read()
returns a list of ClipboardItems
objects. To read images from the clipboard, you can iterate through the list of ClipboardItems
to retrieve them.
async function getClipboardContents () {
try {
const clipboardItems = await navigator.clipboard.read() // List of clipboardItems
for (const clipboardItem of clipboardItems) {
// types: Array of available MIME types in ClipboardItem.
for (const type of clipboardItem.types) {
// Returns a Promise that resolves with a Blob parsed using the requested MIME type.
// If the MIME type is not found, an error is returned.
const blob = await clipboardItem.getType(type)
if (type === 'text/plain') { // Text
// The text() method in the Blob interface returns a Promise.
// This Promise is resolved with a string containing the Blob's content, interpreted as UTF-8.
const text = await blob.text()
console.log(text)
} else if (type === 'image/png') { // Image
const url = URL.createObjectURL(blob)
console.log(url)
}
}
}
} catch (e) {
console.error(`Failed to paste: ${e}` )
}
}
Event Listening#
The Clipboard API inherits from EventTarget (a DOM interface implemented by objects that can receive events and create listeners), so it also has event listening capabilities. Currently, it has not been discovered how to listen for events, so you can use the previous document.addEventListener
for listening.
document.addEventListener('paste', async (e) => {
e.preventDefault();
// Multiple or image content
getClipboardContents()
// When there is only text
if (navigator.clipboard) {
text = await navigator.clipboard.readText();
}
else {
text = e.clipboardData.getData('text/plain'); // Early syntax
}
});
This article is synchronized and updated to xLog by Mix Space
The original link is https://liu-wb.com/posts/default/clipboard