The problem
Typically, this is how copying text is done (taken from here):
- Create a
<textarea>
element to be appended to the document. Set itsvalue
to the string that we want to copy to the clipboard. - Append said
<textarea>
element to the current HTML document. - Use
HTMLInputElement.select()
to select the contents of the<textarea>
element. - Use
document.execCommand('copy')
to copy the contents of the<textarea>
to the clipboard. - 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:
- There may be some flashing due to the temporary
<textarea>
element. - 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
- Use
addEventListener
to attach our custom event handler, which will override the current data with our text. - Use
document.execCommand('copy')
to trigger the copy action. - 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.
Works very well. Thanks for posting this tip.