While this example is not a definitive solution, it focuses on being future-proof rather than backwards compatible. Successful testing occurred in the following browsers on Windows 7 64-bit:
- Microsoft Internet Explorer 11 (11.0.9600.17843)
- Google Chrome 46 (46.0.2490.80 m)
- Mozilla Firefox 41 (41.0.2)
- Opera 32 (32.0.1948.44)
If you test it and find it to be working in other browsers, please make note of the browser, version and platform (OS) in the comments.
At the time of this writing the ClipboardEvent API is still an experimental technology, and is subject to change. This reference will be updated as such changes that are material to this example come to my attention.
This consists of a simple object with two properties and a single method.
var clipboard =
{
data : '',
intercept : false,
hook : function (evt)
{
if (clipboard.intercept)
{
evt.clipboardData.setData('text/plain', clipboard.data);
evt.preventDefault();
clipboard.intercept = false;
clipboard.data = '';
}
}
};
Name | Default | Description |
---|---|---|
data | empty string | This property holds the data that we want placed into the clipboard. |
intercept | false | Indicates whether or not the hook should intercept the triggered event. |
hook | function | Function that will be called whenever the copy event is triggered. |
In this example, we intercept the copy
event on the window
object. This event is triggered both from the Copy
browser context menu item or when the user presses the Ctrl+c
(or other platform appropriate keyboard shortcut). Because of this, we do not need to capture keystrokes as a separate event handler to trigger the same code.
window.addEventListener('copy', clipboard.hook);
Unless and until this event listener is removed, every attempt to copy anything on the page will hit our event handler.
Our clipboard.hook
event handler is called when the copy
event is triggered. It first looks to see if it should intercept the method, using it's own intercept
property. If so, it takes the value currently in clipboard.data
and puts it on the clipboard. The call to preventDefault
then stops the default action - copying whatever was selected into the clipboard - from happening, and overriding our data.
function (evt)
{
if (clipboard.intercept)
{
evt.clipboardData.setData('text/plain', clipboard.data);
evt.preventDefault();
clipboard.intercept = false;
clipboard.data = '';
}
}
Here we also clear our clipboard.data
and set clipboard.intercept
to false. Failing to do this last update will result in every attempt to copy data using standard means (context menu and keyboard shortcuts) on the page being intercepted by our method, instead of the user copying what they thought they were copying. Unless this is your intention, it's best not to frustrate users, even if you can't think of a reason they might want to copy anything else on the page.
While it might be possible to do otherwise, the example here only sets textual data, and that is our primary use case.
We want to use a DOM event - in this case, a button click - trigger our copy function. Not surprisingly, the first thing we want to do when the button is click is set the value of clipboard.data
to the desired data.
Next, we're going to check DOM support for window.clipboardData
. While it's true that Microsoft has (mostly) deprecated this object, if it does exist, then that means that the code is running in an old version of Internet Explorer. If that's the case, we don't need to trigger a copy event; we can just populate the clipboard using window.clipboardData.setData
method.
Otherwise, we need to trigger the copy event. But before doing that, we should set clipboard.intercept
to true. Otherwise, our hook won't execute, and the default action will occur.
function onButtonClick ()
{
clipboard.data = txt.value;
if (window.clipboardData)
{
window.clipboardData.setData('Text', clipboard.data);
}
else
{
clipboard.intercept = true;
document.execCommand('copy');
}
}
Take a minute to check out the entry for the Clipboard API at CanIUse.com. There are a few things important to note.
-
There are known issues with Safari (Mac and iOS) and older versions of both Firefox (pre 41) and Chrome (pre 31) where the copy event could not be triggered via
document.execCommand
. -
No browser tested thus far is able to successfully create a
ClipboardEvent
object using the documented constructor. -
According to the documentation, the
document.execCommand
method should only be available when the document is in design mode, but at the time of this writing (Oct 2015), that is not the case.