A better way to copy text to Clipboard in JavaScript

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 <textarea> 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.

5 3 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Sonny
Sonny
3 years ago

Works very well. Thanks for posting this tip.

0
Would love your thoughts, please comment.x
()
x