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
event.clipboardData.setData in copy event
提问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.
我查看了许多帖子,但找不到以下两个问题的明确当前答案,因为标准和浏览器支持似乎一直在不断变化。
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?
根据标准,在“复制”事件处理程序中使用 event.clipboardData.setData 更改剪贴板是否合法?
最新版本的 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 click
handler:
如果您需要触发复制事件(而不仅仅是处理用户通过浏览器 UI 发出的复制请求),则必须使用document.execCommand('copy')
. 它只适用于某些处理程序,例如click
处理程序:
document.getElementById("copyBtn").onclick = function() {
document.execCommand('copy');
}
Modern browsers support both methods
现代浏览器支持这两种方法
- Firefox supports both
clipboardData
in thecopy
/cut
/paste
events (since Firefox 22) andexecCommand('copy')
from user actions (since Firefox 41) - Chrome also supports both (the latter was added in Chrome 43- or perhaps 42?)
- caniuse.com claims that Safari 12 has complete support, versions up to 9.1 didn't support
execCommand('copy')
. - MS Edge Platform Statuslists IE/Edge as supporting the Clipboard APIs as of 2019, unlike when this answer was first written (2016).
- 火狐支持
clipboardData
在copy
/cut
/paste
事件(因为火狐22)和execCommand('copy')
从用户的动作(因为火狐41) - Chrome 也支持两者(后者是在 Chrome 43中添加的- 或者可能是 42?)
- caniuse.com 声称 Safari 12 完全支持,版本高达 9.1 不支持
execCommand('copy')
. - MS Edge Platform Status将 IE/Edge 列为自 2019 年起支持剪贴板 API,这与首次编写此答案时(2016 年)不同。
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
更多资源
- Specification: Clipboard API and events
- The Definitive Guide to Copying and Pasting in JavaScript(2014) - more information on clipboard API interoperability in browsers, including support for the "copy"/"paste" events without a selection and support for multiple formats.
- Pages tagged "Clipboard API" on MDN
- 规范:剪贴板 API 和事件
- JavaScript 中复制和粘贴的权威指南(2014) - 有关浏览器中剪贴板 API 互操作性的更多信息,包括对“复制”/“粘贴”事件的支持,而无需选择和支持多种格式。
- 在 MDN 上标记为“剪贴板 API”的页面
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.clipboard
will 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");
}