30

我查看了很多帖子,但找不到以下两个问题的明确当前答案,因为标准和浏览器支持似乎一直在不断变化。

  1. 根据标准,在“复制”事件处理程序中使用 event.clipboardData.setData 更改剪贴板是否合法?

  2. 最新版本的 Chrome/FF/Safari/IE/Chrome iOS/Android/iPhone 是否正确支持此功能?

4

4 回答 4

56

截至 2016 年,剪贴板 API 确实在积极开发中,但从那时起情况就趋于稳定:

支持使用 event.clipboardData.setData()

event.clipboardData.setData()规范允许在事件处理程序内部更改剪贴板'copy'(只要事件不是合成的)。

请注意,您需要阻止事件处理程序中的默认操作,以防止您的更改被浏览器覆盖:

document.addEventListener('copy', function(e){
  e.clipboardData.setData('text/plain', 'foo');
  e.preventDefault(); // default behaviour is to copy any selected text
});

要触发复制事件,请使用 execCommand

如果您需要触发复制事件(而不仅仅是处理用户通过浏览器 UI 发出的复制请求),则必须使用document.execCommand('copy'). 它只适用于某些处理程序,例如click处理程序:

document.getElementById("copyBtn").onclick = function() {
  document.execCommand('copy');
}

现代浏览器支持这两种方法

https://github.com/garykac/clipboard/blob/master/clipboard.md有一个execCommand(cut / copy / paste).

您可以使用下面的代码段对此进行测试,请对结果发表评论。

更多资源

测试用例

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

Async Clipboard API 将提供一种更简单的方式来管理剪贴板

实现后,navigator.clipboard将让您编写如下代码:

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 开始发布部分实现,他们发表了一篇关于新 API 的文章

于 2016-04-03T01:37:23.793 回答
15

您也可以将其转换为调用自己的处理程序并将其删除的函数

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');
}
于 2017-04-18T22:39:20.660 回答
3

将元素 id 与复制事件绑定,然后获取选定的文本。您可以替换或修改文本。获取剪贴板并设置新文本。要获得准确的格式,您需要将类型设置为“text/hmtl”。您也可以将其绑定到文档而不是元素。

 $(ElementId).bind('copy', function(event) {
    var selectedText = window.getSelection().toString(); 
    selectedText = selectedText.replace(/\u200B/g, "");

    clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
    clipboardData.setData('text/html', selectedText);

    event.preventDefault();
  });
于 2017-08-24T09:18:22.203 回答
2

为此,我们可以使用浏览器 API。它对我有用

 async copyClipboard(string){    
   await navigator.clipboard.writeText(string);
   console.log("Text copied");
}
于 2020-05-12T07:53:09.310 回答