1, Introduction

Browsers allow JavaScript scripts to read and write to the clipboard to automatically copy or paste content.

In general, scripts should not alter the user’s clipboard in a way that does not meet the user’s expectations. However, there are times when this is convenient, such as the “one-click copy” feature, where the user clicks a button and the specified content automatically goes to the clipboard.

Currently, there are three ways to implement clipboard operations.

  • Document.execCommand() method
  • Asynchronous Clipboard API
  • copy event and paste event

This article introduces each of these three methods.

copy text to chipboard using javascript

2, Document.execCommand() method

Document.execCommand() is the traditional method for manipulating the clipboard and is supported by various browsers.

It supports the three operations of copy, cut and paste.It supports the three operations of copy, cut and paste.

  • document.execCommand('copy')
  • document.execCommand('cut')
  • document.execCommand('paste')

(1)Copy Operation

To copy, first select the text, then call document.execCommand('copy') and the selected text will go to the clipboard.

1
2
3
const inputElement = document.querySelector('#input');
inputElement.select();
document.execCommand('copy');

In the above example, the script first selects the text inside the input box inputElement (inputElement.select()) and then document.execCommand('copy') copies it to the clipboard.

Note that the copy operation is best placed inside an event listener function, triggered by the user (e.g., if the user clicks a button). Some browsers may report an error if the script is executed autonomously.Note that the copy operation is best placed inside an event listener function, triggered by the user (e.g., if the user clicks a button). Some browsers may report an error if the script is executed autonomously.

(2)Paste operation

When pasting, calling document.execCommand('paste') will output the contents of the clipboard to the current focus element.

1
2
3
const pasteText = document.querySelector('#output');
pasteText.focus();
document.execCommand('paste');

(3)Disadvantages

The Document.execCommand() method is convenient, but it has some disadvantages.

First, it can only copy the selected content to the clipboard, and cannot write arbitrary content to the clipboard.

Second, it is a synchronous operation, so if you copy/paste a lot of data, the page will lag. Some browsers also pop up a prompt box asking for user permission, at which point the page loses response before the user can make a choice.

To solve these problems, browser vendors have proposed the asynchronous Clipboard API.

3, Asynchronous Clipboard API

The Clipboard API is the next generation of clipboard manipulation, more powerful and logical than the traditional document.execCommand() method.

All its operations are asynchronous, returning Promise objects without causing page lag. Moreover, it can put any content (e.g. images) into the clipboard.

The navigator.clipboard property returns the clipboard object, through which all operations are performed.

1
const clipboardObj = navigator.clipboard;

If the navigator.clipboard property returns undefined, then the current browser does not support this API.

Since users may put sensitive data (e.g. passwords) in the clipboard, allowing scripts to read it arbitrarily poses a security risk, so this API has a number of security restrictions.

First, Chrome requires that only pages with the HTTPS protocol can use this API, although the development environment (localhost) allows the use of non-encrypted protocols.

Second, the user’s permission needs to be explicitly obtained when calling it. Permissions are implemented using the Permissions API, and there are two clipboard-related permissions: clipboard-write (write permission) and clipboard-read (read permission). write permission" is automatically granted to the script, while “read permission” must be granted with the user’s explicit consent. In other words, writing to the clipboard can be done automatically by the script, but when reading the clipboard, the browser will pop up a dialog asking the user if he/she agrees to read it.

permission

Also, note that the script always reads the clipboard of the current page. One problem with this is that if you paste the relevant code into Developer Tools and run it directly, it may report an error, because the current page is then the Developer Tools window, not the web page.

1
2
3
4
(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
})();

If you take the above code, paste it into the Developer Tools and run it, it will report an error. Because when the code is run, the Developer Tools window is the current page, and this page does not have the DOM interface that the Clipboard API depends on. A workaround is to put the code inside setTimeout() to delay the run and quickly click on the browser page window before calling the function to make it the current page.

1
2
3
4
setTimeout(async () => {
 const text = await navigator.clipboard.readText();
 console.log(text);
}, 2000);

After pasting the above code into the developer tool and running it, give a quick click on the page window of the web page to make it the current page so that no error is reported.

4, Clipboard object

The Clipboard object provides four methods to read and write to the clipboard. They are all asynchronous methods that return Promise objects.

4.1 Clipboard.readText()

The Clipboard.readText() method is used to copy the text data inside the clipboard.

1
2
3
4
5
6
7
 document.body.addEventListener(
  'click',
  async (e) => {
    const text = await navigator.clipboard.readText();
    console.log(text);
  }
)

In the above example, when the user clicks on the page, the text inside the clipboard is output. Note that the browser will pop up a dialog box at this point asking the user if they agree to the script reading the clipboard.

If the user does not agree, the script will report an error. In this case, you can use the try... .catch structure to handle error reporting.

1
2
3
4
5
6
7
8
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()

The Clipboard.read() method is used to copy the data inside the clipboard, either text data or binary data (e.g. images). This method requires explicit permission from the user.

The method returns a Promise object. Once the state of the object is resolved, an array is obtained, each member of which is an instance of the ClipboardItem object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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 clipboard item, each of which has a ClipboardItem.types property and a ClipboardItem.getType() method.

The ClipboardItem.types property returns an array whose members are the MIME types available for the clipboard item, for example, if a clipboard item can be pasted in HTML format or in plain text format, then it has two MIME types (text/html and text/plain) ).

The ClipboardItem.getType(type) method is used to read the data of the clipboard item, returning a Promise object. The method accepts the MIME type of the clipboard item as a parameter and returns the data of that type, which is required, otherwise an error is reported.

4.3 Clipboard.writeText()

The Clipboard.writeText() method is used to write the text content to the clipboard.

1
2
3
4
5
6
document.body.addEventListener(
  'click',
  async (e) => {
    await navigator.clipboard.writeText('Yo')
  }
)

The above example is a script that writes text data to the clipboard after the user clicks on a web page.

This method does not require user permission, but it is best to also put it in try.... .catch to prevent error reporting.

1
2
3
4
5
6
7
8
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()

The Clipboard.write() method is used to write arbitrary data to the clipboard, either as text data or as binary data.

This method accepts a ClipboardItem instance as an argument, indicating the data to be written to the clipboard.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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 an image to the clipboard. Note that Chrome currently only supports writing images in PNG format.

ClipboardItem() is a constructor provided natively by the browser to generate a ClipboardItem instance, which accepts as a parameter an object whose key name is the MIME type of the data, and whose key value is the data itself.

The following example takes the same clipboard item and writes its value in multiple formats to the clipboard, one with text data and another with binary data for different occasions of pasting.

1
2
3
4
5
6
7
8
9
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]);
}

5, copy event, cut event

The copy event will be triggered when the user puts data into the clipboard.

The following example takes the text that the user puts into the clipboard and converts it to uppercase.

1
2
3
4
5
6
7
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 property of the event object contains the 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) :Get the clipboard data, you need to specify the data type.
  • Event.clipboardData.clearData([type]) :To clear the clipboard data, you can specify the data type. If no type is specified, all types of data will be cleared.
  • Event.clipboardData.items :An array-like object that contains all the clipping items, although there is usually only one clipping item.

The following example intercepts the user’s copy operation and puts the specified content into the clipboard.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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, the default clipboard operation is cancelled using e.preventDefault(), and then the script takes over the copy operation.

The cut event is triggered when the user performs a cut operation, and it is handled exactly the same as the copy event, which also gets the cut data from the Event.clipboardData property.

6, paste event

The paste event is triggered when the user uses the clipboard data and performs a paste operation.

The following example intercepts the paste operation and the script takes out the data from the clipboard.

1
2
3
4
5
document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const text = await navigator.clipboard.readText();
  console.log('Pasted text: ', text);
});

Reference http://www.ruanyifeng.com/blog/2021/01/clipboard-api.html