DEV Community

Hiep Bao Le
Hiep Bao Le

Posted on • Originally published at komsciguy.com

A better way to copy text to Clipboard in JavaScript

Originally posted on my blog.

The problem

Typically, this is how copying text is done (taken from here):

  1. Create a <textarea> element to be appended to the document. Set its value to the string that we want to copy to the clipboard.
  2. Append said <textarea> element to the current HTML document.
  3. Use HTMLInputElement.select() to select the contents of the <textarea> element.
  4. Use document.execCommand('copy') to copy the contents of the <textarea> to the clipboard.
  5. Remove the <textarea> element from the document.

The code looks like this:

function copyToClipboard(text) {
  const el = document.createElement('textarea');
  el.value = text;
  document.body.appendChild(el);
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
};

There are two problems with this approach:

  1. There may be some flashing due to the temporary element.
  2. It will unselect whatever the user is selecting.

We can work around both, but the function will become much longer.

Solution

When the user initiates a copy action, the user agent fires a clipboard event name copy.

W3C Specification

  1. Use addEventListener to attach our custom event handler, which will override the current data with our text.
  2. Use document.execCommand('copy') to trigger the copy action.
  3. Use removeEventListener to remove our event handler.
function copyToClipboard(text) {
  const listener = function(ev) {
    ev.preventDefault();
    ev.clipboardData.setData('text/plain', text);
  };
  document.addEventListener('copy', listener);
  document.execCommand('copy');
  document.removeEventListener('copy', listener);
}

Bonus

You can even copy rich text!

function copyRichText(text) {
  const listener = function(ev) {
    ev.preventDefault();
    ev.clipboardData.setData('text/html', text);
    ev.clipboardData.setData('text/plain', text);
  };
  document.addEventListener('copy', listener);
  document.execCommand('copy');
  document.removeEventListener('copy', listener);
}
copyRichText('<i>Markup</i> <b>text</b>. Paste me into a rich text editor.');

Browser compatibility

According to MDN Web Docs, this should work on all major browsers except Internet Explorer.

Top comments (4)

Collapse
 
josemunoz profile image
José Muñoz

it would be better if "copyToClipboard" didn't had the DOM side-effects since its taking more responsibility that just copying a text to the host's clipboard, see:

Collapse
 
itsjzt profile image
Saurabh Sharma

there is a clipboard API too. Its is not widely supported for now and it also asks for user permission before writing to clipboard / reading from clipboard.

Collapse
 
parammittal16 profile image
PARAM MITTAL

Nice.....

Collapse
 
b0yblake profile image
Lichhuun

I think "except Internet Explorer" it's not perfect. Try to support IE (>8) your code is much more beauty