In my work, I will encounter some requirement scenarios, such as automatic uploading after pasting images, and pasting text and images in rich text editor. These are related to Clipboard API. Here I will explain the contents of the latest Clipboard API.

Clipboard API demo code address: Github

Clipboard API capabilities

What does the Clipboard API do?

From the introduction of MDN, two points can be summed up:

  • Allows us to read and write the contents of the clipboard;
  • This allows us to listen for copy, cut, and paste events (that is, copy, cut, paste) and do some extra processing.

Clipboard API components

The Clipboard API consists of Clipboard, ClipboardItem and Clipboard Event.

  • ClipboardAn interface is an abstraction of a clipboard and provides a way to read and write to a clipboard. We’re throughClipboardTo operate the system clipboard, such as the contents of any user clipboard.
  • ClipboardItemAn interface is an abstraction of the content in a clipboard. For example, if we select a piece of text on a web page, right click and select Copy, the copied content will act as oneClipboardItemThere is. More on that later.
  • Clipboard EventAs the name suggests, copy and paste these events. By listeningcopy,cut,pasteFor these events, we can do some extra processing when the user is copying and pasting. For example, when you copy content from my blog, I can change the content you copy and add a copyright message 😆.

Operating shears

The Web provides the Clipboard interface, but instead of creating it manually, we manipulate the Clipboard through the navigator.clipboard property. Navigator.clipboard has four methods:

  • readText: Used to read the text content of the clipboard
  • read: We may copy some non-text content, such as images, files, etc.readMethod provides this functionality
  • writeText: Writes text to the clipboard
  • write: Writes to the clipboard in a variety of formats, such as an image or a formatted HTML fragment

Each of the above methods returns a Promise. The difference is that the read method returns the read content in a Promise.

navigator.clipboard.readText().then((text) = > { console.log(text) });
Copy the code

Why do they always return promises?

Operation of the clipboard can easily leak user privacy and cause some security problems. Therefore, the method of operation of the clipboard will request permission from the user and proceed only after the user agrees. At this time, the promise state will change to Resolved and if the user refuses, Then the Promise state changes to Rejected.

The following is a detailed example to explain, you can click the Demo page for practical operation, understanding will be more in-depth.

Because the Clipboard API is relatively new and not supported by all browsers, the following examples run in the latest version of Chrome.

Read the text

Reading text is easy, just call the readText method to read the text from the clipboard:

navigator.clipboard.readText().then((text) = > { console.log(text) });
Copy the code

Read the content in MIME format

throughread()Methods can read text, pictures, files and other content at presentread()Method is only implemented in the latest Chromeimage/pngFormat function. throughread()The method reads oneClipboardItemsThe array. Let’s say we find an image on a web page, right click copy, and print out the data we read:

ClipboardItem has the following properties and methods:

  • typesProperty: contains a format list of the content you just copied,
  • getType()Method: This method takes a string representing the type, such astext/html, returns a Promise through which we can get the Blob type of the content corresponding to the format.

[“text/ HTML “, “image/ PNG “], because we are copying images, but we are actually copying two types of content:

  • text/html: This is HTML text, for example I copied the Vue logo, the actual content is as follows:
    <meta charset="utf-8"><img src="https://cn.vuejs.org/images/logo.png" alt="vue logo">
    Copy the code
  • image/png: This is the content of the picture we copied.

Call the types attribute:

navigator.clipboard.read().then(clipboardItems= > {
    console.log(clipboardItems[0].types)
})
// ["text/html", "image/png"]
Copy the code

The blob.text () method is used to get the corresponding text format of the Blob content. Look at the corresponding text/ HTML content:

navigator.clipboard.read().then(async clipboardItems => {
    const blob = await clipboardItems[0].getType('text/html')
    const text = await blob.text()
    console.log(text)
})
// <meta charset="utf-8"><img src="https://cn.vuejs.org/images/logo.png" alt="vue logo">
Copy the code

We can read and display all the contents of the clipboard:

  • For text, display its content directly
  • For images, the binary data of the image is read and rendered

Example code is as follows:

navigator.clipboard.read().then(async clipboardItems => {
    const promises = clipboardItems.map(async (item: ClipboardItem) => {
        // Get all types and the corresponding contents
        const promises = item.types.map(async type= > {const typeData = await item.getType(type)
            let data = ' '
            if (/text/.test(type)) {
                data = awaittypeData? .text? (1)}.else if (/image/.test(type)) {
                // Read the image content as DataUrl
                data = URL.createObjectURL(typeData)
            }
            return { type, data, }
        })
        const typeList = await Promise.all(promises)
        return typeList
    })
    clipboardData.clipboardItemList = await Promise.all(promises)
    console.log(clipboardData.clipboardItemList)
})
Copy the code

You can see this code in action here. Copy an image and click the “Get the clipboard MIME type content” button to display all the clipboard MIME type content below.

Write to Clipboard

Writing text to the Clipboard is as simple as reading it, using writeText() without saying more:

navigator.clipboard.writeText('This is the text I'm writing to my clipboard.').then(() = > {
    alert('Write succeeded, can copy content into text box')})Copy the code

We can also write images and other content to the Clipboard using the clipboard.write () method. The argument to the write() method is an array of ClipboardItems.

The properties and methods of ClipboardItem are described above. Here is how to create a ClipboardItem instance. To create an instance of ClipboardItem, pass in an object whose key represents the type of the content, such as text/ HTML, and whose value is Blob data. For example, create an HTML fragment:

const clipboardItem = new ClipboardItem({
    'text/html': new Blob([ ' This is the HTML format of the copy '] and {type: 'text/html'})})// Then write it to the clipboard
navigator.clipboard.write([ clipboardItem ]).then(() = > {
    alert('Write succeeded')})Copy the code

Note that the latest Chrome browser supports the write() method, but only one clipboardItem can be passed in the array.

At this point, if we get the clipboard content or paste it into an input box that supports rich text (such as wechat), we can see what we wrote.

Response to Clipboard events

The Clipboard API also allows us to respond to events like copy and paste. Simply add a copy cut or paste event listener to a specific element to listen for these events.

We listen for these events in two ways:

  • incopycutChange the content stored in the clipboard when the event occurs. For example, when you copy a paragraph from CSDN blog and paste it into your own blog, you will find that the pasted content has a paragraph of copyright information, which is done by using these events.
  • inpasteThe clipboard content is read when an event occurs. For example, a rich text editor automatically uploads images to the server after pasting them.

Within these time handlers, we can operate navigator.clipboard directly using the read and write methods described above:

document.querySelector('.input').addEventListener('copy'.() = > {
    navigator.clipboard.read().then(clipboardItems= > {
      console.log(clipboardItems[0].types)
  })
});
Copy the code

However, the browser’s support for navigator.clipboard is not perfect, so the old API can be used to read and write to the clipboard. When a Copy Cut or Paste event is triggered, the clipboardData property on the event object lets us read or write to the clipboard.

interceptpasteThe event

Event. clipboardData is a DataTransfer object that provides two methods:

  • getData(format): To read the contents of the clipboard, you need to pass in the type of content to read, such asgetData('text/html');
  • setData(format, data)Method to set the contents of the clipboard as a string representing the type and the corresponding data content of the type.

For example, we intercept the paste operation in an input box and change the paste behavior:

const onPaste = e= > {
    // 
    const text = e.clipboardData.getData('text/plain')
    e.target.value = 'This is what happens when the code is manually changed :\n\n' + text
    e.preventDefault()
}
document.querySelector('.input').addEventListener('paste', onPaste)
Copy the code

ClipboardData has an Items property, which is a list of DatatransferItems from which we can retrieve all the contents of the clipboard. Using items, we will get the pictures in the clipboard during pasting and perform processing such as uploading:

const onPaste = e= > {
    // Class array object
    const items = [ ...e.clipboardData.items ]
    let file;
    items.forEach((item, index) = > {
        const { type } = item
        if (type === 'image/png') {
            // Get file data using getAsFile of DataTransferItem
            file = URL.createObjectURL(item.getAsFile())
            const formData = new FormData()
            formData.append('file', file);
            // Upload here
        }
    })
    e.preventDefault()
}
document.querySelector('.input').addEventListener('paste', onPaste)
Copy the code

interceptcopy,cutThe event

By intercepting copy and cut events, we can change what the user copies:

const onCopy = e= > {
    console.log(e.clipboardData)
    const selection = document.getSelection()
    e.clipboardData.setData('text/plain'.'The content you copied has been changed by me!${selection}`)
    e.preventDefault()
}
document.querySelector('.input').addEventListener('copy', onCopy)
Copy the code

You can view the preceding examples on the Demo page.

conclusion

The Clipboard API does not cover a lot of knowledge, but generally has the following three aspects:

  • ClipboardInterfaces provide ways to manipulate the clipboard. Keep the following in mind:
    • throughnavigator.clipboardTo operate the shear plate;
    • There are four methods available (for now) :read()readText().write()writeText(), all return a Promise
    • usenavigator.clipboardAuthorization is requested from the user.
  • ClipboardItemThe interface represents an item in the clipboard. For example, if we right-click on an image and click Copy, an item will be added to the clipboardClipboardItem, stores content in two formats:text/htmlimage/png.
    • useClipboard.read()The data read by the method isClipboardItemAn array composed of;
    • eachClipboardItemThere is atypesProperty that contains the type of all the content it holds, such as:['text/html', 'image/png']
    • eachClipboardItemThere is agetTypeMethod, which returns a Promise, passing in the type of the previous entry to get the corresponding content, such as:getType('text/html')
    • useClipboard.write()Method is created when writing data to a clipboardClipboardItemExample:
      const item = new ClipboardItem({
          'text/html': new Blob([ 'html'])})Copy the code
  • Clipboard Events allow us to intercept copy, cut, and paste events and change the default behavior:
    • The listening events are copy, cut, and paste
    • throughevent.clipboardData.getData(format)Can get clipboard content;
    • throughevent.clipboardData.getData(format, data)You can change what is written to the clipboard during copy and cut.
    • throughevent.clipboardData.itemsCan obtain all the clipboard content, paste automatic upload and other functions

That’s all about the Clipboard API. I hope I can help you

Welcome to follow me, will continue to write more quality blog to share with you. Meanwhile, if you have any questions, welcome to discuss ~

Link to original text