loading...

A better way to copy text to Clipboard in JavaScript

hieplpvip profile image Hiep Bao Le Originally published at komsciguy.com ・2 min read

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.

Discussion

markdown guide
 

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.

 

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:

 

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