grit

grit

Clipboard API: A brand new asynchronous copy and paste API

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:

  1. 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.
  2. 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.

  1. 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.
  2. The blob property value of ClipboardItem 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


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.