Javascript 复制事件中的 event.clipboardData.setData

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36270886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:51:43  来源:igfitidea点击:

event.clipboardData.setData in copy event

javascripthtmldom-eventsw3cclipboarddata

提问by kofifus

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?

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

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

回答by Nickolay

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

到 2016 年,剪贴板 API 确实在积极开发中,但自那时以来情况已经稳定:

Using event.clipboardData.setData() is supported

支持使用 event.clipboardData.setData()

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).

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

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

要触发复制事件使用 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 clickhandler:

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

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

Modern browsers support both methods

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

https://github.com/garykac/clipboard/blob/master/clipboard.mdhas a compatibility table for execCommand(cut / copy / paste).

https://github.com/garykac/clipboard/blob/master/clipboard.md有一个兼容性表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">

Async Clipboard API will provide a simpler way to manage the clipboard

异步剪贴板 API 将提供一种更简单的方法来管理剪贴板

When implemented, navigator.clipboardwill let you write code like this:

实现后,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 starts shipping a partial implementation, and they've published an article about the new API.

Chrome 66 开始发布部分实现,并且他们发布了一篇关于新 API 的文章

回答by Chad Scira

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

回答by Sollymanul Islam

Bind the element id with copy event and then get the selected text. You could replace or modify the text. Get the clipboard and set the new text. To get the exact formatting you need to set the type as "text/hmtl". You may also bind it to the document instead of element.

将元素 id 与 copy 事件绑定,然后获取选定的文本。您可以替换或修改文本。获取剪贴板并设置新文本。要获得确切的格式,您需要将类型设置为“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();
  });

回答by sanzmalz

For this, we can use browser API. It's worked for me

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

 async copyClipboard(string){    
   await navigator.clipboard.writeText(string);
   console.log("Text copied");
}