Clipboard operation Clipboard API tutorial
1. Introduction
The browser allows JavaScript scripts to read and write the clipboard, and automatically copy or paste content.
In general, scripts should not modify the user’s clipboard, so as not to meet the user’s expectations. However, sometimes it can be convenient to do this, such as the “one-click copy” function, the user clicks a button, and the specified content is automatically entered into the clipboard.
Currently, there are three ways to implement clipboard operations.
Document.execCommand()
method- Asynchronous Clipboard API
copy
Events andpaste
events
This article introduces these three methods one by one.
Two, Document.execCommand() method
Document.execCommand()
It is the traditional method of operating the clipboard, which is supported by various browsers.
It supports the three operations of copy, cut and paste.
document.execCommand('copy')
(copy)document.execCommand('cut')
(Cut)document.execCommand('paste')
(Paste)
(1) Copy operation
When copying, first select the text and then call
document.execCommand('copy')
, the selected text will enter the clipboard.
const inputElement = document.querySelector('#input'); inputElement.select(); document.execCommand('copy');
In the above example, the script first selects
inputElement
the text (
inputElement.select()
) in the
input box
, and then
document.execCommand('copy')
copies it to the clipboard.
Note that the copy operation is best placed in the event listener function, triggered by the user (for example, the user clicks a button). If the script is executed autonomously, some browsers may report an error.
(2) Paste operation
When it is pasted, when it is called
document.execCommand('paste')
, the contents of the clipboard will be output to the current focus element.
const pasteText = document.querySelector('#output'); pasteText.focus(); document.execCommand('paste');
(3) Disadvantages
Document.execCommand()
Although the method is convenient, it has some disadvantages.
First, it can only copy the selected content to the clipboard, and cannot write content to the clipboard arbitrarily.
Secondly, it is a synchronous operation. If you copy/paste a large amount of data, the page will freeze. Some browsers will also pop up a prompt box and ask the user for permission. At this time, the page will become unresponsive before the user makes a selection.
In order to solve these problems, browser vendors have proposed an asynchronous Clipboard API.
Three, asynchronous Clipboard API
Clipboard API is the next generation clipboard operation method, which
document.execCommand()
is more powerful and reasonable
than traditional
methods.
All its operations are asynchronous and return Promise objects without causing page jams. Moreover, it can put arbitrary content (such as pictures) into the clipboard.
navigator.clipboard
The property returns the Clipboard object, and all operations are performed through this object.
const clipboardObj = navigator.clipboard;
If the
navigator.clipboard
property is returned
undefined
, it means that the current browser does not support this API.
Since users may put sensitive data (such as passwords) on the clipboard, allowing scripts to read them arbitrarily will cause security risks, so this API has more security restrictions.
First of all, Chrome browser stipulates that only HTTPS protocol pages can use this API.
However, the development environment (
localhost
) allows the use of non-encrypted protocols.
Secondly, the user’s permission needs to be clearly obtained when calling.
The specific implementation of permissions uses the Permissions API. There are two permissions related to the clipboard:
clipboard-write
(write permission) and
clipboard-read
(read permission).
The “write permission” is automatically granted to the script, and the “read permission” must be explicitly granted by the user.
In other words, the script can be automatically completed when writing to the clipboard, but when reading the clipboard, the browser will pop up a dialog box asking whether the user agrees to read.
In addition, it should be noted that what the script reads is always the clipboard of the current page. One problem that this brings is that if you paste the relevant code into the developer tool and run it directly, an error may be reported, because the current page at this time is the window of the developer tool, not a web page.
(async () => { const text = await navigator.clipboard.readText(); console.log(text); })();
If you paste the above code into the developer tool and run it, an error will be reported.
Because when the code is running, the developer tool window is the current page, and there is no DOM interface that the Clipboard API depends on on this page.
One solution is to put the relevant code
setTimeout()
inside to delay running, and quickly click the page window of the browser before calling the function to turn it into the current page.
setTimeout(async () => { const text = await navigator.clipboard.readText(); console.log(text); }, 2000);
After the above code is pasted into the developer tool to run, quickly click on the page window of the webpage to make it the current page, so that no error will be reported.
Fourth, the Clipboard object
The Clipboard object provides four methods for reading and writing the clipboard. They are all asynchronous methods that return Promise objects.
4.1 Clipboard.readText()
Clipboard.readText()
The method is used to copy the text data in the clipboard.
document.body.addEventListener( 'click', async (e) => { const text = await navigator.clipboard.readText(); console.log(text); } )
In the above example, after the user clicks on the page, the text in the clipboard will be output. Note that the browser will pop up a dialog box at this time, asking the user whether to agree with the script to read the clipboard.
If the user disagrees, the script will report an error.
At this time, you can use the
try...catch
structure to handle errors.
async function getClipboardContents() { try { const text = await navigator.clipboard.readText(); console.log('Pasted content: ', text); } catch (err) { console.error('Failed to read clipboard contents: ', err); } }
4.2 Clipboard.read()
Clipboard.read()
The method is used to copy the data in the clipboard, which can be text data or binary data (such as pictures).
This method requires explicit permission from the user.
This method returns a Promise object. Once the state of the object becomes resolved, an array can be obtained, and each array member is an instance of a ClipboardItem object.
async function getClipboardContents() { try { const clipboardItems = await navigator.clipboard.read(); for (const clipboardItem of clipboardItems) { for (const type of clipboardItem.types) { const blob = await clipboardItem.getType(type); console.log(URL.createObjectURL(blob)); } } } catch (err) { console.error(err.name, err.message); } }
The ClipboardItem object represents a single clip item, and each clip item has
ClipboardItem.types
properties and
ClipboardItem.getType()
methods.
ClipboardItem.types
The property returns an array. The members in it are the MIME types available for the clip item. For example, a clip item can be pasted in HTML format or in plain text format, so it has two MIME types (
text/html
and
text/plain
).
ClipboardItem.getType(type)
The method is used to read the data of the clipped item and return a Promise object.
This method accepts the MIME type of the clip item as a parameter, and returns the data of that type. This parameter is required, otherwise an error will be reported.
4.3 Clipboard.writeText()
Clipboard.writeText()
The method is used to write the text content to the clipboard.
document.body.addEventListener( 'click', async (e) => { await navigator.clipboard.writeText('Yo') } )
The above example is that after the user clicks on the web page, the script writes text data to the clipboard.
This method does not require user permission, but it is best to put
try...catch
it inside to prevent errors.
async function copyPageUrl() { try { await navigator.clipboard.writeText(location.href); console.log('Page URL copied to clipboard'); } catch (err) { console.error('Failed to copy: ', err); } }
4.4 Clipboard.write()
Clipboard.write()
The method is used to write arbitrary data to the clipboard, which can be text data or binary data.
This method accepts a ClipboardItem instance as a parameter, which represents the data written to the clipboard.
try { const imgURL = 'https://dummyimage.com/300.png'; const data = await fetch(imgURL); const blob = await data.blob(); await navigator.clipboard.write([ new ClipboardItem({ [blob.type]: blob }) ]); console.log('Image copied.'); } catch (err) { console.error(err.name, err.message); }
In the above example, the script writes a picture to the clipboard. Note that the Chrome browser currently only supports writing images in PNG format.
ClipboardItem()
It is a constructor
ClipboardItem
natively
provided by the browser to generate an
instance. It accepts an object as a parameter. The key name of the object is the MIME type of the data, and the key value is the data itself.
The following example is to write the value of the same clip item in multiple formats to the clipboard, one is text data, and the other is binary data for pasting in different occasions.
function copy() { const image = await fetch('kitten.png'); const text = new Blob(['Cute sleeping kitten'], {type: 'text/plain'}); const item = new ClipboardItem({ 'text/plain': text, 'image/png': image }); await navigator.clipboard.write([item]); }
Five, copy event, cut event
When the user puts data into the clipboard, an
copy
event
will be triggered
.
The following example is to convert the text that the user puts on the clipboard to uppercase.
const source = document.querySelector('.source'); source.addEventListener('copy', (event) => { const selection = document.getSelection(); event.clipboardData.setData('text/plain', selection.toString().toUpperCase()); event.preventDefault(); });
In the above example, the
clipboardData
properties of the
event object
contain clipboard data.
It is an object with the following properties and methods.
Event.clipboardData.setData(type, data)
: To modify the clipboard data, you need to specify the data type.Event.clipboardData.getData(type)
: To obtain clipboard data, you need to specify the data type.Event.clipboardData.clearData([type])
: Clear clipboard data, you can specify the data type. If you do not specify the type, all types of data will be cleared.Event.clipboardData.items
: An array-like object that contains all cut and paste items, but usually there is only one cut and paste item.
The following example is to intercept the user’s copy operation and put the specified content into the clipboard.
const clipboardItems = []; document.addEventListener('copy', async (e) => { e.preventDefault(); try { let clipboardItems = []; for (const item of e.clipboardData.items) { if (!item.type.startsWith('image/')) { continue; } clipboardItems.push( new ClipboardItem({ [item.type]: item, }) ); await navigator.clipboard.write(clipboardItems); console.log('Image copied.'); } } catch (err) { console.error(err.name, err.message); } });
In the above example,
e.preventDefault()
the default operation of canceling the clipboard is
used first
, and then the script takes over the copy operation.
cut
The event is triggered when the user performs a cut operation, and its processing is
copy
exactly the same as the event, and the
Event.clipboardData
cut data
is also obtained from the
attribute.
Six, paste event
When the user uses the clipboard data to paste, an
paste
event
will be triggered
.
The following example is to intercept the paste operation, the data in the clipboard is taken out by the script.
document.addEventListener('paste', async (e) => { e.preventDefault(); const text = await navigator.clipboard.readText(); console.log('Pasted text: ', text); });
Seven, reference link
- Unblocking clipboard access
- Interact with the clipboard
- Multi-MIME Type Copying with the Async Clipboard API
(over)