I have looked at many posts but could not find a clear current answer to the following two questions as it seems standards and browser support has been constantly changing.
Is it a legal operation according to the standard to change the clipboard with event.clipboardData.setData inside a 'copy' event handler?
Do latest versions of Chrome/FF/Safari/IE/Chrome iOS/Android/iPhones support this correctly?
The copy event fires when the user initiates a copy action through the browser's user interface. The event's default action is to copy the selection (if any) to the clipboard. A handler for this event can modify the clipboard contents by calling setData(format, data) on the event's ClipboardEvent.
A clipboard is a temporary storage area for data that the user wants to copy from one place to another. In a word processor application, for example, the user might want to cut text from one part of a document and paste it in another part of the document or somewhere else.
To get to your clipboard history at any time, press Windows logo key + V. From the clipboard history, you can paste and pin frequently used items by choosing an individual item from your clipboard menu. Pinning an item keeps it from being removed from the clipboard history to make room for new items.
Clipboard APIs were indeed in active development as of 2016, but things have stabilized since then:
Changing the clipboard with event.clipboardData.setData()
inside a 'copy'
event handler is allowed by the spec (as long as the event is not synthetic).
Note that you need to prevent the default action in the event handler to prevent your changes from being overwritten by the browser:
document.addEventListener('copy', function(e){ e.clipboardData.setData('text/plain', 'foo'); e.preventDefault(); // default behaviour is to copy any selected text });
If you need to trigger the copy event (and not just handle the copy requests made by the user via the browser UI), you must use document.execCommand('copy')
. It will only work in certain handlers, such as the click
handler:
document.getElementById("copyBtn").onclick = function() { document.execCommand('copy'); }
clipboardData
in the copy
/cut
/paste
events (since Firefox 22) and execCommand('copy')
from user actions (since Firefox 41)execCommand('copy')
.https://github.com/garykac/clipboard/blob/master/clipboard.md has a compatibility table for execCommand(cut / copy / paste)
.
You can test this using the snippet below, please comment with the results.
window.onload = function() { document.addEventListener('copy', function(e){ console.log("copy handler"); if (document.getElementById("enableHandler").checked) { e.clipboardData.setData('text/plain', 'Current time is ' + new Date()); e.preventDefault(); // default behaviour is to copy any selected text } // This is just to simplify testing: setTimeout(function() { var tb = document.getElementById("target"); tb.value = ""; tb.focus(); }, 0); }); document.getElementById("execCopy").onclick = function() { document.execCommand('copy'); // only works in click handler or other user-triggered thread } document.getElementById("synthEvt").onclick = function() { var e = new ClipboardEvent("copy", {dataType: "text/plain", data:"bar"}); document.dispatchEvent(e); } }
<html> <input id="enableHandler" type="checkbox" checked> <label for="enableHandler">Run clipboardData.setData('text/plain', ...) in the "copy" handler</label> <p>Try selecting this text and triggering a copy using</p> <ul> <li><button id="execCopy">document.execCommand('copy')</button> - should work.</li> <li><button id="synthEvt">document.dispatchEvent(clipboardEvent)</button> - should NOT work</li> <li>with keyboard shortcut - should work</li> <li>or from the context menu - should work</li> </ul> <p>If the "copy" handler was triggered, the focus will move to the textbox below automatically, so that you can try pasting from clipboard:</p> <input type="text" id="target" size="80">
When implemented, navigator.clipboard
will let you write code like this:
navigator.clipboard.writeText('Text to be copied') .then(() => { console.log('Text copied to clipboard'); }) .catch(err => { // This can happen if the user denies clipboard permissions: console.error('Could not copy text: ', err); });
Chrome 66 starts shipping a partial implementation, and they've published an article about the new API.
You can also just turn it into a function that calls its own handler and removes it
function copyStringToClipboard (string) { function handler (event){ event.clipboardData.setData('text/plain', string); event.preventDefault(); document.removeEventListener('copy', handler, true); } document.addEventListener('copy', handler, true); document.execCommand('copy'); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With