Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

javascript - event.clipboardData.setData in copy event

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.

  1. Is it a legal operation according to the standard to change the clipboard with event.clipboardData.setData inside a 'copy' event handler?

  2. Do latest versions of Chrome/FF/Safari/IE/Chrome iOS/Android/iPhones support this correctly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Clipboard APIs were indeed in active development as of 2016, but things have stabilized since then:

Using event.clipboardData.setData() is supported

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
});

To trigger the copy event use execCommand

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');
}

Modern browsers support both methods

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.

More resources

Testcase

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">

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...